Python正则表达式匹配单行和多行注释。

4

我将尝试创建一个Python正则表达式,用于PLY,以匹配以下形式的注释:

// some comment

and

/* comment
   more comment */

所以我尝试了一下

t_COMMENT = r'//.+ | /\*.+\*/'

但是这种方法无法支持多行注释,当我尝试使用“点匹配所有”选项来解决这个问题时,会出现以下情况:
t_COMMENT = r'//.+ | (?s) /\*.+\*/'

这会导致“//”注释类型匹配多行。如果我尝试使用两个单独的正则表达式,例如

t_COMMENT = r'//.+' 
t_COMMENT2 = r'(?s) /\*.+\*/'

"//"这种注释方式仍然会匹配多行,就好像启用了“dot matches all”选项。有人知道如何解决这个问题吗?"

1
我强烈怀疑这是一个不好的想法。试图使用复杂的正则表达式进行过多高级(语法)解析,与创建词法分析器/语法分析器系统的初衷背道而驰。我建议您为单行注释和多行开始和结束设置标记。围绕该解析器构建的语法可以丢弃在多行开始和结束之间找到的所有输入。 - Jim Dennis
你能根据你的想法给出一个答案吗? - Zvika
4个回答

9
下面的正则表达式将匹配两种类型的注释:
(?://[^\n]*|/\*(?:(?!\*/).)*\*/)

演示

>>> s = """// some comment
... 
... foo
... bar
... foobar
... /* comment
...    more comment */ bar"""
>>> m = re.findall(r'(?://[^\n]*|/\*(?:(?!\*/).)*\*/)', s, re.DOTALL)
>>> m
['// some comment', '/* comment\n   more comment */']

4
这是对Avinash解决方案的小变化。 pat = re.compile(r'(?://.*?$)|(?:/\*.*?\*/)', re.M|re.S)

2
根据 PLY Doc,可以通过“条件词法分析”来实现。这可能比复杂的正则表达式更易读、更易于调试。他们给出的示例稍微复杂一些,因为它要跟踪嵌套级别和块内的内容。然而,您的情况比较简单,因为您不需要所有这些信息。
多行注释的代码应该像这样:
# I'd prefer 'multi_line_comment', but it appears that 
# state names cannot have underscore in them
states = (
    ('multiLineComment','exclusive'),
)

def t_multiLineComment_start(t):
    r'/\*'
    t.lexer.begin('multiLineComment')          

def t_multiLineComment_end):
    r'\*/'
    t.lexer.begin('INITIAL')           

def t_multiLineComment_newline(t):
    r'\n'
    pass

# catch (and ignore) anything that isn't end-of-comment
def t_multiLineComment_content(t):
    r'[^(\*/)]'
    pass

当然,在常规状态下,你还需要另一个规则来处理 // 注释。

0

这可能是有用的

 (/\*(.|\n)*?*/)|(//.*)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接