Как получить все перекрывающиеся совпадения в регулярном выражении Python, которые могут начинаться в одном и том же месте строки? - PullRequest
1 голос
/ 11 апреля 2019

Как получить все возможные совпадения совпадений в строке в Python с несколькими начальными и конечными точками.

Я попытался использовать модуль regex вместо модуля re по умолчанию, чтобы ввести аргумент overlapped = True, нодо сих пор не хватает некоторых соответствий.

Попытка описать мою проблему с помощью более простой иллюстрации:

Найти все возможные комбинации в строке (axaybzb), начиная с a и заканчивая b

Пробовал следующие коды:

import regex

print(regex.findall(r'a\w+b','axaybzb', overlapped=False))

['axaybzb']

print(regex.findall(r'a\w+?b','axaybzb', overlapped=False))

['axayb']

print(regex.findall(r'a\w+b','axaybzb', overlapped=True))

['axaybzb', 'aybzb']

print(regex.findall(r'a\w+?b','axaybzb', overlapped=True))

['axayb', 'ayb']

Ожидаемый результат будет

['axayb', 'axaybzb', 'ayb', 'aybzb']

Ответы [ 2 ]

1 голос
/ 11 апреля 2019

Regex не является подходящим инструментом, я бы порекомендовал:

  • Идентифицировать все индексы первой буквы во входной строке
  • Определить все индексы второй буквы во входной строке
  • Построить все подстроки на основе этих индексов

код:

def find(str, ch):
    for i, ltr in enumerate(str):
        if ltr == ch:
            yield i

s = "axaybzb"
startChar = 'a'
endChar = 'b'

startCharList = list(find(s,startChar))
endCharList = list(find(s,endChar))

output = []
for u in startCharList:
    for v in endCharList:
           if u <= v:
               output.append(s[u:v+1])
print(output)

выход:

$ python substring.py 
['axayb', 'axaybzb', 'ayb', 'aybzb']
0 голосов
/ 11 апреля 2019

С такими простыми шаблонами, как ваш, вы можете генерировать фрагменты всех последовательных символов в строке и проверять их все на соответствие определенному регулярному выражению для полного соответствия:

import re

def findall_overlapped(r, s):
  res = []                     # Resulting list
  reg = r'^{}$'.format(r)      # Regex must match full string
  for q in range(len(s)):      # Iterate over all chars in a string
    for w in range(q,len(s)):  # Iterate over the rest of the chars to the right
        cur = s[q:w+1]         # Currently tested slice
        if re.match(reg, cur): # If there is a full slice match
            res.append(cur)    # Append it to the resulting list
  return res

rex = r'a\w+b'
print(findall_overlapped(rex, 'axaybzb'))
# => ['axayb', 'axaybzb', 'ayb', 'aybzb']

См. Демонстрационную версию Python

ПРЕДУПРЕЖДЕНИЕ : обратите внимание, что это не сработает, если у вас есть шаблон, проверяющий левый или правый контекст, с предвзятыми или обращенными взглядами на обоих концах шаблона, так как этот контекст будетбудет потеряно при переборе по строке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...