Проверка на наличие нескольких символов в строке в определенном порядке. Питон

Рейтинг: 2Ответов: 2Опубликовано: 17.01.2023

Есть список b, состоящий из нескольких строк. Нужно проверить содержится ли в каждой конкретной строке слово (например, 'anton'). Должны быть буквы этого слова, не обязательно подряд (даже чаще не подряд - т.е. такая строка подходит: 'asrngktnv5jonj'), но именно в этом порядке. В слове совпадают последняя и третья с конца буквы. В моей "изящной" конструкции такой код:

for i in range(len(b)):
    if ('a' in b[i] and 't' in b[i] and 'o' in b[i] and b[i].count('n') >= 2 and b[i].find('a') < b[i].find('n') < b[i].find('t') < b[i].find('o') < b[i].rfind('n')):
        print(i + 1, end=' ')

В нем я проверяю наличие каждой из букв в строке списка, а очередность - через сравнение значений индексов.

Проблема:

  1. проверка на наличие букв тяжеловесная.
  2. код не работает - в тестах где в строках много разных символов этот код где-то находит искомое слово, а где-то не находит (хотя нужные буквы и нужной последовательности там имеются).

Отсюда два вопроса:

  • как проверить наличие букв в строке более компактно. Вообще, можно ли сделать конструкцию, в которой бы был список или кортеж из искомых символов и они искались в строке. Типа: if ('a', 'n', 't', 'o') in b - ?
  • как проверить располагаются ли эти символы в нужной последовательности? (помня, что в искомом слове есть еще две одинаковые буквы)?

P.S. что касается проверки, делал ее в том числе и через срезы, типа:

for i in b:
    while b[i] != 'a':
        b[i] = b[i][1:]
    count += 1

перебирал нужные буквы, пока не находилась искомая я удалял первый символ строки. Когда буква находилась - к счетчику добавлял 1. В итоге при count = 5 условие выполнялось. Но, тут тоже результат нулевой.

Ответы

▲ 4Принят

Вариант с регуляркой

import re

lines = ['asrngktnv5jonj', 'asrngkfnv5jonj', 'afdjflewkjcneckdbctlbnldjcodsnnnnnnnnnnn']
text = 'anton'
r = re.compile('.*'.join(re.escape(text)))
for line in lines:
    if r.search(line):
        print(f'Строка `{line}` содержит `{text}`')
    else:
        print(f'Строка `{line}` НЕ содержит `{text}`')
Строка `asrngktnv5jonj` содержит `anton`
Строка `asrngkfnv5jonj` НЕ содержит `anton`
Строка `afdjflewkjcneckdbctlbnldjcodsnnnnnnnnnnn` содержит `anton`
▲ 2

Двигаясь по образцу subseq ищем следующий символ в тексте. Поиск начинается со следующей позиции в тексте (переменная i):

def is_subseq(subseq, text):
    i = -1
    for c in subseq:
        i = text.find(c, i + 1)
        if i == -1:
            return False
    return True


print(is_subseq('anton', 'anton'))
print(is_subseq('anton', 'asrngktnv5jonj'))
print(is_subseq('anton', 'asrngkfnv5jonj'))
print(is_subseq('anton', 'afdjflewkjcneckdbctlbnldjcodsnnnnnnnnnnn'))
$ python subseq.py
True
True
False
True