2013-09-01 2 views
2

Python3.3, OS X 7,5Python RegEx запроса недостающих перекрывающиеся подстроки

Я пытаюсь найти все экземпляры 4-символа подстроки определяется следующим образом:

  • Первый символ = 'N'
  • Второй символ = Ничего, кроме «Р»
  • Третий символ = «S» или «T»
  • Четвертый символ = Ничего, кроме «Р»

Мой запрос выглядит следующим образом:

re.findall(r"\N[A-OQ-Z][ST][A-OQ-Z]", text) 

Это работает только в одном частном случае, когда пересекаются две подстроки. Этот случай включает в себя следующие 5character подстроку:

'...NNTSY...' 

Запрос ловит первый 4-символ подстроки («ННЦ»), но не второй 4-символа подстроки («NTSY»).

Это моя первая попытка регулярных выражений, и, очевидно, я что-то упустил.

ответ

0

Из документации Python 3 (курсив мой):

 
$ python3 -c 'import re; help(re.findall)' 
Help on function findall in module re: 

findall(pattern, string, flags=0) 
    Return a list of all non-overlapping matches in the string. 

    If one or more capturing groups are present in the pattern, return 
    a list of groups; this will be a list of tuples if the pattern 
    has more than one group. 

    Empty matches are included in the result. 

Если вы хотите перекрывающихся экземпляров, используйте regex.search() в цикле. Вы должны скомпилировать регулярное выражение, потому что API для нескомпилированных регулярных выражений не принимает параметр для указания начальной позиции.

def findall_overlapping(pattern, string, flags=0): 
    """Find all matches, even ones that overlap.""" 
    regex = re.compile(pattern, flags) 
    pos = 0 
    while True: 
     match = regex.search(string, pos) 
     if not match: 
      break 
     yield match 
     pos = match.start() + 1 
1

Вы можете это сделать, если повторно двигатель не потребляет символы, как это соответствует их, что возможно с упреждающего утверждений:

import re 
text = '...NNTSY...' 
for m in re.findall(r'(?=(N[A-OQ-Z][ST][A-OQ-Z]))', text): 
    print(m) 

Выход:

NNTS 
NTSY 

Имея все в рамках утверждения работает, но также чувствует себя странно. Другой способ принимает N из утверждения:

for m in re.findall(r'(N(?=([A-OQ-Z][ST][A-OQ-Z])))', text): 
    print(''.join(m)) 
Смежные вопросы