为什么PLY对待正则表达式与Python / re不同?

时间:2014-02-22 22:03:45

标签: python regex ply

一些背景知识:

我正在编写一个解析器来检索带有标记语言的网站的信息。标准库作为wikitools,...对我来说不起作用,因为我需要更具体,并根据我的需要调整它们,这使我和问题之间存在一层复杂性。 Python +"简单"正则表达式使我难以识别不同的标记之间的依赖关系#34;以透明的方式使用标记语言 - 显然我需要在此旅程结束时到达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 ---会丢失,以防它与#34;搜索&#34;相比(并且在与#34匹配的情况下没有任何内容;匹配&#34;)。显然这很重要,因为--无法区分---(或===来自===),即头条新闻,无法区分......无法区分。

那么为什么PLY在标准Python /正则表达式方面表现不同? (以及如何? - 无法在文档中找到某些内容,或者在stackoverflow中找到它。)

我猜这是我对PLY的理解,因为这个工具已经存在了很长一段时间,也就是说这种行为是我想的意思。我能找到的唯一相关信息与different groups有关,但没有解释识别正则表达式本身的不同行为。我也没有在ply-hack中找到任何东西。

我忽略了一些愚蠢的简单吗?

为了比较,这里标准的Python /正则表达式:

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

(正如预期的那样,首先是&#34;搜索&#34;的结果,&#34;匹配&#34的第二个;)

我的设置:我正在使用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 个答案:

答案 0 :(得分:4)

ply lexmatch regular expression has different groups than a usual re中的答案也有帮助。在lex.py中:

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

注意VERBOSE标志。这意味着re引擎会忽略正则表达式中的空格字符。所以r'-- .* --'实际上意味着r'--.*--',它确实完全匹配像'--- foobar ---'这样的字符串。有关详细信息,请参阅re.VERBOSE的文档。