Python PLY:非法字符'+';
我正在使用ply开发python解析器,我必须以以下形式解析输入:Python PLY:非法字符'+';,python,regex,python-2.7,ply,Python,Regex,Python 2.7,Ply,我正在使用ply开发python解析器,我必须以以下形式解析输入: VAR VAR1 001 +000 000 000 000 其中,代码将创建一个名为VAR 1的变量,然后将值0赋给它 我为实例编写的正则表达式是: t_INST = r'[\+|-]0[ ][0-9][0-9][0-9][ ][0-9][0-9][0-9][ ][0-9][0-9][0-9][ ][0-9][0-9][0-9]' 但是,在运行我的程序时,PLY会打印以下内容: Illegal character '+'
VAR VAR1 001
+000 000 000 000
其中,代码将创建一个名为VAR 1的变量,然后将值0赋给它
我为实例编写的正则表达式是:
t_INST = r'[\+|-]0[ ][0-9][0-9][0-9][ ][0-9][0-9][0-9][ ][0-9][0-9][0-9][ ][0-9][0-9][0-9]'
但是,在运行我的程序时,PLY会打印以下内容:
Illegal character '+'
复制机如下所示:
import ply.lex as lex
tokens = ['INST']
t_INST = r'[+-]0[ ](\d{3}[ ]){3}\d{3}';
t_ignore = ' \t'
def t_error(t):
print("Illegal character '%s'" % t.value[0])
t.lexer.skip(1)
lexer = lex.lex()
def parse(input_string):
ret = []
lexer.input (input_string)
while True:
tok = lexer.token()
if not tok:
break # No more input
ret.append((tok.type, tok.value))
return ret
print parse("+0 000 000 000")
您不必在字符类中转义
+
。您可以使用:
t_INST = r'[+|-]0[ ][0-9][0-9][0-9][ ][0-9][0-9][0-9][ ][0-9][0-9][0-9][ ][0-9][0-9][0-9]'
this-----^
无论如何,您可以这样缩短正则表达式:
t_INST = r'[+|-]0[ ][0-9]{3}[ ][0-9]{3}[ ][0-9]{3}[ ][0-9]{3}'
甚至:
t_INST = r'[+|-]0[ ]([0-9]{3}[ ]){3}[0-9]{3}'
还注意到您使用了[+-]
,这是一个字符类,不适用于替换,因此您必须将其更改为[+-]
因此,最后一个正则表达式(使用\d
作为[0-9]
的快捷方式)是:
t_INST = r'[+-]0[ ](\d{3}[ ]){3}\d{3}'
顺便说一句,您的示例文本显示:
+000 000 000 000
但您使用的正则表达式与此匹配:
+0 000 000 000 000
因此,如果要匹配的数据是+000
,则必须将正则表达式更改为:
t_INST = r'[+-](\d{3}[ ]){3}\d{3}'
该行:
print parse("+0 000 000 000")
与您声明的输入格式不匹配
VAR VAR1 001
+000 000 000 000
如果实际数据的格式与+0 000 000
相同,则实际需要:
t_INST = r'[+-]0\s(?:\d{3}\s){2}\d{3}'
…其输出为:
[('INST','+0 000')]
您应该使用\d表示字符,还应该使用{}表示重复序列:[\+-](?:\d{3}\s?{4}为什么使用反斜杠?您可能希望在正常的上下文中这样做,但在角色类中没有意义。实际上,除非|
是有效的第一个字符,否则您可能也希望[+-]
,而不是[+-]
。顺便说一句,将您的复制器(同时尽可能保持最小)扩展到完整且可验证的程度会有所帮助,如中所示。现在,有人需要做相当多的工作来重现这个bug。请在问题中提供我的解析器的MVCE。或者至少在没有广告的地方(如果你使用的是adblock,你可能没有注意到pastebin.com上到处都是广告);这是一个很好的选择。这是我在回答中给出的正则表达式,使用\s
作为快捷方式和非捕获组。这听起来更像是对我问题的评论。此外,对于OP的测试数据,您使用了{2}
,并且应该是{3}
,不,它确实应该是{2}
。他们的评论对实际使用的数据格式具有误导性。(这就是为什么我花了大量的时间强迫他们提供一个真正的复制者,而不是直接写一个答案)…这里的问题(即,我选择写一个竞争性答案而不是评论这个答案的不良行为)你写了一个答案,但实际上没有一个真正的复制者,这可能会造成他们的问题,因此没有保证你真的知道OP的问题是什么。即使re.compile(r'[\+\-]].match('+')
不起作用,我也同意有充分的理由进行推测,但事实并非如此:最初的代码很糟糕,但(可测试!)没有在最初给出的任何理由上被破坏……事实上,re.compile(r'[\+-]0[\+]0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]')。匹配('+0 000')
返回匹配项。