与 re 但不是 lex 匹配的正则表达式
Regular expression matching with re but not lex
我正在尝试解析文件以重新格式化它。为此,我需要能够区分整行注释和行尾注释。我已经能够让 lex 正确识别整行注释,但我在行尾注释方面遇到问题。
例如:“a = 0; //这;有效;很好”但是“a = 0; //这,有效;无效; ".
最让我困惑的是 re 能够毫无问题地识别这两个注释,而 lex 却不能。
这里是相关代码(FL=full line, EL=end of line):
tokens = (
'EQUAL',
'SEMICOLON',
'FL_COMMENT',
'EL_COMMENT',
'STRING'
)
t_EQUAL = r'='
t_SEMICOLON = r';'
def t_FL_COMMENT(t):
r"""(^|\n)\s*(//|\#).*"""
return t
def t_EL_COMMENT(t):
r"""(?<=;)\s*(//|\#).*"""
return t
def t_STRING(t):
r"""(".*")|([a-zA-Z0-9\</][\w.\-\+/]*)"""
return t
def t_newline(t):
r"""\n"""
t.lexer.lineno += len(t.value)
t_ignore = ' \t'
def t_error(t):
print("Illegal character '%s' on line %d" % (t.value[0], t.lineno))
t.lexer.skip(1)
def t_eof(t):
return None
lexer = lex.lex()
lexer.input(file_contents)
for token in lexer:
print(token)
Lex(包括 Ply 品种)构建词法分析器,而不是正则表达式搜索器。与通常尝试扫描整个输入以查找模式的正则表达式库不同,lex 尝试确定与当前输入点匹配的模式。然后它将输入推进到紧随其后的点,并尝试在该点找到匹配模式。等等。 文本中的每个字符都包含在某个匹配的标记中。(尽管某些标记可能会被丢弃。)
您实际上可以利用这一事实来简化您的正则表达式。在这种情况下,例如,由于您可以依靠 t_FL_COMMENT
来匹配确实出现在行首的注释,因此任何其他注释都不能位于行首。所以不需要回顾:
def t_FL_COMMENT(t):
r"""(^|\n)\s*(//|\#).*"""
return t
def t_EL_COMMENT(t):
r"""(//|\#).*"""
return t
(\n|^)
的替代方法是 (?m)^
(它启用多行模式,以便 ^
可以在换行符之后匹配,也可以在字符串的开头匹配) .
我正在尝试解析文件以重新格式化它。为此,我需要能够区分整行注释和行尾注释。我已经能够让 lex 正确识别整行注释,但我在行尾注释方面遇到问题。
例如:“a = 0; //这;有效;很好”但是“a = 0; //这,有效;无效; ".
最让我困惑的是 re 能够毫无问题地识别这两个注释,而 lex 却不能。
这里是相关代码(FL=full line, EL=end of line):
tokens = (
'EQUAL',
'SEMICOLON',
'FL_COMMENT',
'EL_COMMENT',
'STRING'
)
t_EQUAL = r'='
t_SEMICOLON = r';'
def t_FL_COMMENT(t):
r"""(^|\n)\s*(//|\#).*"""
return t
def t_EL_COMMENT(t):
r"""(?<=;)\s*(//|\#).*"""
return t
def t_STRING(t):
r"""(".*")|([a-zA-Z0-9\</][\w.\-\+/]*)"""
return t
def t_newline(t):
r"""\n"""
t.lexer.lineno += len(t.value)
t_ignore = ' \t'
def t_error(t):
print("Illegal character '%s' on line %d" % (t.value[0], t.lineno))
t.lexer.skip(1)
def t_eof(t):
return None
lexer = lex.lex()
lexer.input(file_contents)
for token in lexer:
print(token)
Lex(包括 Ply 品种)构建词法分析器,而不是正则表达式搜索器。与通常尝试扫描整个输入以查找模式的正则表达式库不同,lex 尝试确定与当前输入点匹配的模式。然后它将输入推进到紧随其后的点,并尝试在该点找到匹配模式。等等。 文本中的每个字符都包含在某个匹配的标记中。(尽管某些标记可能会被丢弃。)
您实际上可以利用这一事实来简化您的正则表达式。在这种情况下,例如,由于您可以依靠 t_FL_COMMENT
来匹配确实出现在行首的注释,因此任何其他注释都不能位于行首。所以不需要回顾:
def t_FL_COMMENT(t):
r"""(^|\n)\s*(//|\#).*"""
return t
def t_EL_COMMENT(t):
r"""(//|\#).*"""
return t
(\n|^)
的替代方法是 (?m)^
(它启用多行模式,以便 ^
可以在换行符之后匹配,也可以在字符串的开头匹配) .