Регулярное выражение соответствия новой строки перед словом в python - PullRequest
0 голосов
/ 14 января 2012

У меня есть шаблон: "\ nvariable WORD"

Этот шаблон часто появляется в строке, и я хочу список индексов, в которых этот шаблон отображается. «СЛОВО» исправлено и не меняется от экземпляра к экземпляру, но «переменная» различается по содержанию и длине.

В Python я знаю, что это соответствует всем WORD и возвращает их индексы в списке:

contents="some long string"
print [m.start() for m in re.finditer('WORD',contents)]

Короче говоря, как мне найти индексы всех "переменных" после \ n, но до "СЛОВА"?

Ответы [ 4 ]

2 голосов
/ 14 января 2012

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

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

С другой стороны, нотация EBNF (расширенная форма Бэкуса-Наура) намного легче понять и поддерживать.

from simpleparse.parser import Parser

grammar = r"""
<space>      := [ \t]
<newline>    := '\n'
<identifier> := [A-Za-z_],[A-Za-z0-9z_]*
match        := newline,identifier,space+,'WORD'
<junk>       := newline*,identifier,space+,-'WORD',(identifier/space)*
data         := (match/junk)*
"""

parser = Parser(grammar, 'data')

data = 'some junk\nvariable1 WORD\nvariable2 some ' +\
       'junk\nvariable3 WORD\nvariable4 some other ' +\
       'junk\nvariable5 WORD'

(start, matches, stop) = parser.parse(data)

print [ start for name, start, stop, other in matches ]

Будет напечатано:

[9, 44, 85]
2 голосов
/ 14 января 2012

Будет ли этого достаточно?

>>> import re
>>> s = '\nvariable1 WORD\nvariable2 WORD\nvariable3 WORD\nvariable4 WORD\nvariable5 WORD'
>>> re.findall(r'\n(\w+)\s+WORD', s)
['variable1', 'variable2', 'variable3', 'variable4', 'variable5']

Для чего нужны индексы?

0 голосов
/ 16 января 2012

Ах, хорошо, оказалось, что текст на самом деле содержал возвратные символы ctrl-M вместо символов новой строки, что сводило меня с ума.Я удалил их и просто использовал:

[m.start() for m in re.finditer('\w+\sWORD',contents)]

Спасибо за помощь!Simpleparser также работает, конечно.

0 голосов
/ 14 января 2012

Возможно, вам придется сместить индексы с начальных точек в зависимости от вашей цели.Если через '\ n' вы ожидаете переводы строки, вам нужно будет включить флаг MULTILINE в компиляцию.

import re

mytext='\nvar1 WORD\nvar2 WORD\nvar3 WORD'
#compile a pattern to find the 'var*' after \n
pat = re.compile('\n(.*?)\s+WORD')

results = re.finditer(pat,mytext)

for result in results:
    print result.start()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...