与 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)^(它启用多行模式,以便 ^ 可以在换行符之后匹配,也可以在字符串的开头匹配) .