Почему 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
Больше подробностей.