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

Posted

技术标签:

【中文标题】用于匹配单行和多行注释的 Python 正则表达式。【英文标题】:Python regex for matching single line and multi line comments. 【发布时间】:2014-11-07 11:40:28 【问题描述】:

我正在尝试为 PLY 创建一个 python 正则表达式,它将匹配表单的 cmets

// some comment

/* comment
   more comment */

所以我尝试了

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

但这不允许多行 cmets,当我尝试使用“点匹配所有”选项(如

)解决此问题时
t_COMMENT = r'//.+ | (?s) /\*.+\*/'

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

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

“//”注释类型仍然匹配多行,就像选择了点匹配所有选项一样。

有人知道怎么解决吗?

【问题讨论】:

我强烈怀疑这是一个坏主意。尝试使用复杂的正则表达式进行过多的高级(语法)解析是创建词法分析器/解析器系统的对立面。我建议你有单行注释的标记,多行开始和结束。围绕该解析器构建的语法可以丢弃在多行开头和结尾之间找到的所有输入。 你能根据你的想法给出答案吗? 【参考方案1】:

下面的正则表达式将匹配两种类型的 cmets,

(?://[^\n]*|/\*(?:(?!\*/).)*\*/)

DEMO

>>> 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 */']

【讨论】:

【参考方案2】:

这里是 Avinash 解决方案的一个小变化。

pat = re.compile(r'(?://.*?$)|(?:/\*.*?\*/)', re.M|re.S)

【讨论】:

【参考方案3】:

根据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

当然,您必须在常规状态下为// cmets 设置另一条规则。

【讨论】:

【参考方案4】:

这也许有用

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

【讨论】:

以上是关于用于匹配单行和多行注释的 Python 正则表达式。的主要内容,如果未能解决你的问题,请参考以下文章

java 单行注释 替换为 多行注释

注释的正则表达式,但不在“字符串”内/不在另一个容器中

使用正则表达式匹配 Lua 多行字符串和注释

Python中如何添加注释

为啥正则表达式引擎允许/自动尝试在输入字符串的末尾进行匹配?

python中的注释