当前位置:   article > 正文

C语言多行注释的正则表达式_c语言多行注释匹配正则表达式

c语言多行注释匹配正则表达式

本文主要采用 POSIX 标准下的扩展正则表达式 (POSIX-extended) 风格, 并使用了一些 POSIX 未定义但比较常用的特性.

1 背景知识

不同正则表达式引擎有些微的差异, 常用的正则表达式引擎罗列如下:
Perl, PCRE, PHP, .NET, Java, JavaScript, XRegExp, VBScript, Python, Ruby, Delphi, R, Tcl, POSIX 等. (参见 https://www.regular-expressions.info/tutorial.html)

基础概念此处不再赘述, 下面讲一些后面用到的 POSIX 标准中可能未定义的特性.

1.1 前向匹配 (Lookahead)

参见 https://www.regular-expressions.info/lookaround.html)

  • ?= (positive lookahead)
    Pattern1(?=Pattern2)
    
    • 1
    匹配一个符合 Pattern1 的字符串, 并且它的后续是符合 Pattern2 的.
  • ?! (negative lookahead)
    Pattern1(?!Pattern2)
    
    • 1
    匹配一个符合 Pattern1 的字符串, 并且它的后续是符合 Pattern2 的.

1.2 分组与捕获 (Grouping & Capturing)

参见 https://www.regular-expressions.info/brackets.html

  • ?: (Non-Capturing Groups)

    (?:Pattern)
    
    • 1

    禁用小括号所表示的分组的默认捕获功能, 若不禁用, 则正则表达式引擎会将括号内的 Pattern 所匹配的字符串暂存起来, 带来不必要的开销.

    分组的作用与本文无关, 故不再赘述. 感兴趣者可参阅本节链接.

2 正则表达式

2.1 难点分析

难点在于正则表达式是贪婪的 (是满足某个模式的最大匹配), 然而C语言注释是以 /* 开始, 遇到第一个 */ 结束, 是最小匹配, 因而下面的写法是错误的

\/\*(.|\n)*\*\/		if . exclude newline	
\/\*.*\*\/			if . include newline
  • 1
  • 2

若有多个块注释, 则会从第一个块注释的开始匹配到最后一个块注释的结尾.

因此我们需要使用正则表达式使得模式中间不得出现 */.

2.2 容易理解的版本

\/\*(?:\*(?!\/)|[^\*])*\*\/
  • 1

这个方案比较直观, 必须使用前向匹配, 了解前向匹配以后就很容易理解, 然而一些正则表达式引擎可能不支持前向匹配.

该方案参考了 stackoverflow 上的回答.

2.3 更巧妙的版本

\/\*(?:[^\*]|\*+[^\/\*])*\*+\/
  • 1

这个方案就没那么直观了.

前面的 /* 很好理解, 结尾的模式则是 */ 前面可以有若干( ≥ 0 \ge0 0)个 *.

中间的模式为 (a) 若干( ≥ 1 \ge1 1)个 * + 非 / 亦非 * 的结尾; (b)* 的字符 两者的随机重复组合, 可以看到, 由于 (a) (b) 均不以 * 结尾, 且 (a) (b) 内不会出现 */, 故中间的模式不可能出现 */. 此外, 正是由于 (a) (b) 均不以 * 结尾, 故结尾的模式要补上若干个 * .

此处使用 ?: 是为了性能优化, 对于不支持该特性的正则表达式直接去掉即可.

该方案参考了 stackexchange 上的回答.

3 测试

推荐一个测试网站, 体验极佳
https://www.regextester.com/93553

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号