优化?
我在使用以下正则表达式时遇到问题:
/^s*(/?*{1,2}(s*(b.*b)s*(*/)?)?|*/?s*)$/g
我想知道我是否可以改善这个表达方式?另外,如果有人能发现这个表达式有问题,你能注意一下吗?这是我的现场演示。它适用于我在下面设置的所有条件
测试约束
这些匹配
/**
/*
*
*/
/** Javadoc */
/* Block */
* Multi-line
/* Single Line */
/** A
/** A */
/* A
/* A */
这些不应该
7 * 8
// Regular comment
结果
将匹配替换为:// $3
我成功地转换了它们,尽管其中一些有尾随的空白:
//
//
//
// Javadoc
// Block
// Multi-line
// Single Line
// A
// A
// A
// A
正则表达式解释
/
^ Line start
s* 0 or more white-space
( Start group 1
/? forward-slash (OPTIONAL)
*{1,2} 1 to 2 asterisks
( Start group 2
s* 0 or more white-space
( Start group 3
b Start word boundry
.* 0 or more of anything
b End word boundry
) End group 3
s* 0 or more white-space
( Start group 4 (OPTIONAL)
* 0 or more asterisks
/ Forward-slash
)? End group 4
)? End group 2 (OPTIONAL)
| OR
* Asterisk
/? Forward-slash (OPTIONAL)
s* 0 or more white-space
) End group 1
$ Line end
/
g Global; match all
当您必须考虑字符串嵌入、转义和行延续时,解析 C/C++ 样式注释会稍微复杂一些。
这还需要单字符消耗直通方法(在检查所有其他方法之后(。既然如此,在众多可能的匹配交替中,您只参与一项 - C 样式评论/* */
。
因此,在全局搜索和大量匹配的情况下,只有一个匹配项会让您休息,例如捕获组 1 匹配项。当然,在您的情况下,简单的更换不会削减它。
因此,您必须处于全局查找(但不是替换(循环中。每个匹配项都将是源字符串的一部分,不会跳过任何部分,因此每个匹配项都将附加到目标字符串中。
在循环期间,当捕获组 1 匹配(C 样式注释(时,您可以执行不那么简单的替换以使其成为注释C++,然后将该结果附加到目标字符串。
这就是它的要点。如果您使用的任何语言都无法做到这一点,那么它就无法正确完成,这是肯定的!
以下是执行转换为//
的正则表达式列表,当您捕获 C 样式注释时,它们必须按出现顺序执行(例如,符号是 Perl(:
# s{ ^ /* (?: [^Sn] | *)* }{// }xmg;
# s{ ^ (?: [^Sn] | *)* */ $ }{// }xmg;
# s{ ^ $ }{// }xmg;
# s{ ^ (?: [^Sn] | *)+ }{// }xmg;
# s{ (?<![s*]) (?: [^Sn] | *)+ $ }{}xmg;
# s{ (?<![s*]) (?: [^Sn] | *)* */ $ }{}xmg;
这是在查找循环中使用的正则表达式(如上所述(。这个正则表达式可以在任何 Perl 新闻组找到,它是常见问题解答的一部分。
# (?:(/*[^*]**+(?:[^/*][^*]**+)*/)|//(?:[^\]|\n?)*?n)|(?:"(?:\[Ss]|[^"\])*"|'(?:\[Ss]|[^'\])*'|[Ss][^/"'\]*)
# -----------------------------------------------------------------
(?: # Comments
( # (1 start)
/* # Start /* .. */ comment
[^*]* *+
(?: [^/*] [^*]* *+ )*
/ # End /* .. */ comment
) # (1 end)
|
// # Start // comment
(?: [^\] | \ n? )*? # Possible line-continuation
n # End // comment
)
|
(?: # Non - comments
"
(?: \ [Ss] | [^"\] )* # Double quoted text
"
| '
(?: \ [Ss] | [^'\] )* # Single quoted text
'
| [Ss] # Any other char
[^/"'\]* # Chars which doesn't start a comment, string, escape,
# or line continuation (escape + newline)
)