Как разрезать строку, где начало и конец определяются двумя разными подстроками?

#python #string #list #string-matching

#python #строка #Список #сопоставление строк

Вопрос:

Итак, у меня есть список таких строк, как этот:

 list_strings=["YYYYATGMBMSSBAHHH","CCCCUINDAKSLLL","HHHHKJSHAKJJKKKK","ERRREEJK","XZXZOOOOYYYFFFFAKSXXX","RRRRRKJUUUUNNNNNGYRRRRRR","HHHHSDAFF"]
 

И у меня есть два списка шаблонов для поиска в каждой строке:

 forward_patterns=['ATG', 'KJ', 'OOOO','UI']
reverse_patterns=['GY', 'AKS','BA','JK']
 

Я хочу, чтобы каждая строка в list_strings была нарезана с позиции одного forward_patterns шаблона до позиции одного reverse_patterns шаблона (оба, начальный и конечный шаблоны также должны быть удалены). Строка должна быть нарезана только один раз для каждого списка шаблонов, учитывая только первое найденное вхождение. Не имеет значения, какой из шаблонов внутри любого из списков шаблонов найден и используется для нарезки

Мой вывод в этом случае будет таким:

 list_strings=["MBMSS","ND","SHATGKJ","untrimmed","YYYFFFF","UUUUNNNNN","untrimmed"]
 

Я пробовал использовать эти циклы for, но, к сожалению, он не обрезает ни одну из них:

 for i in range(len(list_strings)):
    for pf in forward_patterns:
        beg=list_strings[i].find(pf)
        for pr in reverse_patterns:
            end=list_strings[i].rfind(pr)
            if(beg !=-1 and end !=-1):
                list_strings[i]=list_strings[i][beg len(pf):end]
            else:
                list_strings[i]="untrimmed"
 

По сути, я получаю список всех «необрезанных», но я не знаю, почему:

 list_strings=["untrimmed","untrimmed","untrimmed","untrimmed","untrimmed","untrimmed","untrimmed"]
 

Что может быть не так с моим кодом?
Заранее спасибо за любой ответ!

Комментарии:

1. почему «AAAMBMSSBA» становится «MBMSS»? нет прямого шаблона «AAA»

2. извините, я исправлю

Ответ №1:

На основе последнего обновления:

 res_list = []

for s in list_strings:
    upatedString = s
    for f in forward_patterns:
        if f in upatedString:
            upatedString = upatedString[upatedString.index(f) len(f):]
            break
    for r in reverse_patterns:
        if r in upatedString:
            upatedString = upatedString[:upatedString.index(r)]
            break
    
    if len(upatedString) == len(s):
        res_list.append("Untrimmed")
    else:
        res_list.append(upatedString)

res_list
 

Комментарии:

1. Извините, я отредактировал свой ввод для большей ясности, раньше это немного вводило в заблуждение. Потому что в большинстве случаев обратный шаблон находится не в конце строки, а в середине. Та же ситуация и для шаблонов forward . Шаблоны обычно находятся где-то в середине строк, поэтому я не использовал «startswith» и «endswith». Еще раз извините, потому что предыдущий ввод вводил в заблуждение

2. @Ok, тогда вам нужно заменить шаблоны независимо от того, где они находятся в строке? тогда почему бы не поместить их все в один список?

3. По сути, я хочу для каждой строки найти любой из шаблонов forward и вырезать все, что находится слева от него (включая сам шаблон). То же самое для обратных шаблонов: найдите один из них в обратном порядке и вырежьте все справа от него (включая сам шаблон). Они находятся в двух списках, потому что я хочу сохранить только подмножество строки, которая находится между одним из прямых и одним из обратных шаблонов.

4. @tadeufontes хорошо, я полагаю, что я понял вашу точку зрения, попробуйте новое обновление

Ответ №2:

Ваш пример немного сбивает с толку. Я не понимаю, почему ‘ERRREEJK’ не обрезан, даже если ‘JK’ находится в обратном шаблоне oO. Может быть, это то, что вы ищете?

 list_strings=["YYYYATGMBMSSBAHHH","CCCCUINDAKSLLL","HHHHKJSHAKJJKKKK","ERRREEJK","XZXZOOOOYYYFFFFAKSXXX","RRRRRKJUUUUNNNNNGYRRRRRR","HHHHSDAFF"]
forward_patterns=['ATG', 'KJ', 'OOOO','UI']
reverse_patterns=['GY', 'AKS','BA','JK']
 
new_strings = []
for string in list_strings:
    for pattern in forward_patterns:
        _temp = string.split(pattern,1)
        if len(_temp) == 2:
            _temp = _temp[1]
            break
        else:
            _temp = _temp[0]
    for pattern in reverse_patterns:
        _temp = _temp.rsplit(pattern,1)[0]
        if len(_temp) == 2:
            break
    if string == _temp:
        new_strings.append('untrimmed')
    else:
        new_strings.append(_temp)
 

Комментарии:

1. спасибо за ответ. причина этого в том, что для того, чтобы строка была обрезана, она должна содержать по крайней мере один прямой шаблон и один обратный шаблон