Почему PLY обрабатывает регулярные выражения иначе, чем Python/re?

Немного предыстории:

Я пишу парсер для извлечения информации с сайтов на языке разметки. Стандартные библиотеки, такие как wikitools, ... не работают для меня, потому что мне нужно быть более конкретным, и адаптация их к моим потребностям ставит слой сложности между мной и проблемой. Python + "простое" регулярное выражение привело меня к трудностям в прозрачной идентификации различных зависимостей между разными "токенами" в языке разметки - так что, очевидно, мне нужно было прийти к PLY в конце этого путешествия.

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

Вот так:

import ply.lex as lex

text = r'--- 123456 ---'
token1 = r'-- .* --'
tokens = (
   'TEST',
)
t_TEST = token1

lexer = lex.lex(reflags=re.UNICODE, debug=1)
lexer.input(text)
for tok in lexer:
    print tok.type, tok.value, tok.lineno, tok.lexpos

результаты в:

lex: tokens   = ('TEST',)
lex: literals = ''
lex: states   = {'INITIAL': 'inclusive'}
lex: Adding rule t_TEST -> '-- .* --' (state 'INITIAL')
lex: ==== MASTER REGEXS FOLLOW ====
lex: state 'INITIAL' : regex[0] = '(?P<t_TEST>-- .* --)'
TEST --- 123456 --- 1 0

Последняя строка удивительна - я бы ожидал первого и последнего - быть пропущенным в --- 123456 --- в случае, если оно сопоставимо с "поиском" (и ничто в случае, если оно сопоставимо с "сопоставлением"). Очевидно, что это важно, как тогда -- нельзя отличить от --- (или же === от ===), то есть заголовки, нумерация, ... не могут быть дифференцированы.

Так почему же PLY ведет себя иначе для стандартного Python/regex? (и как? - не удалось найти что-либо в документации или здесь, в stackru).

Я предполагаю, что это больше мое понимание PLY, так как инструмент существует уже довольно давно, то есть это поведение присутствует намеренно, я думаю. Единственная как-то связанная информация, которую я мог найти, касается сделок с разными группами, но не объясняет иное поведение идентификации регулярных выражений. Я тоже ничего не нашел в ply-hack.

Я пропускаю что-то глупое простое?

Для сравнения вот стандартный Python / regex:

import re

text = r'--- 123456 ---'
token1 = r'-- .* --'

p = re.compile(token1)

m = p.search(text)
if m:
    print 'Match found: ', m.group()
else:
    print 'No match'

m = p.match(text)
if m:
    print 'Match found: ', m.group()
else:
    print 'No match'

дает:

Match found:  -- 123456 --
No match

(как и ожидалось, первое - результат поиска, второе - совпадение)

Мои настройки: я работаю со spyder - это дисплей терминала при запуске:

Python 2.7.5+ (default, Sep 19 2013, 13:49:51) 
[GCC 4.8.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.

Imported NumPy 1.7.1, SciPy 0.12.0, Matplotlib 1.2.1
Type "scientific" for more details.

Спасибо за ваше время и помощь.

1 ответ

Решение

The answer in ply lexmatch regular expression has different groups than a usual re helps here too. In lex.py:

c = re.compile("(?P<%s>%s)" % (fname,f.__doc__), re.VERBOSE | self.reflags)

Обратите внимание на VERBOSE флаг. Это означает re engine ignores the whitespace characters in your regexps. Так r'-- .* --' really means r'--.*--', which indeed matches completely a string like '--- foobar ---', Смотрите документацию re.VERBOSE Больше подробностей.

Другие вопросы по тегам