我在使用php和regex从C源代码中删除单行注释时遇到问题。
/* */
条评论已删除,因此剩下的就是//
条评论。
首先:
我有这个正则表达式:$content = ereg_replace('^\/\/.*$', '', $content);
这将删除整个文件(不仅包含^//comment$
的所有行)。我假设因为它贪婪的搜索,但我怎么能让它变得非贪婪?我怎样才能让它为所有符合条件的线做到?
第二次:
问题是在字符串"//shall not be removed"
中不应删除它们。我怎样才能做到这一点?当我发现"
字符时,我在思考它应该跳过它,但我不知道该怎么做。
感谢所有帮助的人,我真的很喜欢它。
答案 0 :(得分:1)
这将匹配所有单行注释,但是用双引号"
包含的注释。甚至那些他们在评论中说的话!
(?=([^"\\]*(\\.|"([^"\\]*\\.)*[^"\\]*"))*[^"]*$)//.*$
<强> Live demo 强>
保留所有权利答案 1 :(得分:1)
为避免字符串陷阱,一种方法是首先匹配您想要避免的内容并捕获它或跳过它。
自PHP 5.3起, ereg_
函数已被弃用,但始终可以使用它们:
$result = ereg_replace('("([^\\\"]|\\\.)*")|//[^' . "\n" . ']*|/\*\**([^*]|\*\**[^*/])*\*\**/', '\1', $str);
它有效,但如果你与preg版本(它有很多功能来改善模式)进行比较,表现非常糟糕:
$pattern2 = '~
" [^"\\\]* (?s: \\\. [^"\\\]* )*+ " # double quoted string
(*SKIP)(*F) # forces the pattern to fail and skips the previous substring
|
/
(?:
/ .* # singleline comment
|
\* # multiline comment
[^*]* (?: \*+(?!/) [^*]* )*+
(?: \*/ )? # optional to deal with unclosed comments
)
~xS';
$result = preg_replace($pattern2, '', $str);
preg版本比ereg_版本快450倍。
子模式的详细信息 [^*]* (?: \*+(?!/) [^*]* )*+
:
此子模式描述了多行注释的内容,因此所有注释都在/*
和第一个*/
之间:
[^*]* # all that is not an asterisk (can be empty)
(?: # open a non capturing group:
# The reason of this group is to handle asterisks that
# are not a part of the closing sequence */
\*+ # one or more asterisks
(?!/) # negative lookahead : not followed by /
# (it is a zero-width assertion, in other words it's only a test
# and it doesn't consume characters)
[^*]* # zero or more characters that are not an asterisk
)*+ # repeat the group zero or more times (possessive)
字符串/*aaaa**bbb***cc***/
的正则表达式引擎走(大约):
/*
aaaa**bbb***cc***/
/\*
[^*]* (?: \*+(?!/) [^*]* )*+ \*/
成功
/*
aaaa
**bbb***cc***/
/\*
[^*]*
(?: \*+(?!/) [^*]* )*+ \*/
成功
/*aaaa**bbb***cc***/
/\* [^*]*
(?: \*+(?!/) [^*]* )*+
\*/
尝试群组
/*aaaa
**
bbb***cc***/
/\* [^*]* (?:
\*+
(?!/) [^*]* )*+ \*/
成功
/*aaaa**
b
bb***cc***/
/\* [^*]* (?: \*+
(?!/)
[^*]* )*+ \*/
已验证
/*aaaa**
bbb
***cc***/
/\* [^*]* (?: \*+(?!/)
[^*]*
)*+ \*/
成功
/*aaaa**bbb***cc***/
/\* [^*]*
(?: \*+(?!/) [^*]* )*+
\*/
尝试群组
/*aaaa**bbb
***
cc***/
/\* [^*]* (?:
\*+
(?!/) [^*]* )*+ \*/
成功
/*aaaa**bbb***
c
c***/
/\* [^*]* (?: \*+
(?!/)
[^*]* )*+ \*/
已验证
/*aaaa**bbb***
cc
***/
/\* [^*]* (?: \*+(?!/)
[^*]*
)*+ \*/
成功
/*aaaa**bbb***cc***/
/\* [^*]*
(?: \*+(?!/) [^*]* )*+
\*/
尝试群组
/*aaaa**bbb***cc
***
/
/\* [^*]* (?:
\*+
(?!/) [^*]* )*+ \*/
成功
/*aaaa**bbb***cc***
/
/\* [^*]* (?: \*+
(?!/)
[^*]* )*+ \*/
失败 >/*aaaa**bbb***cc
**
*/
/\* [^*]* (?:
\*+
(?!/) [^*]* )*+ \*/
回溯
/*aaaa**bbb***cc**
的*
强>/
/\* [^*]* (?: \*+
的(?!/)
强>[^*]* )*+ \*/
验证
/*aaaa**bbb***cc***/
/\* [^*]* (?: \*+(?!/)
[^*]*
)*+ \*/
成功
/*aaaa**bbb***cc***/
/\* [^*]*
(?: \*+(?!/) [^*]* )*+
\*/
尝试群组
/*aaaa**bbb***cc**
*
/
/\* [^*]* (?:
\*+
(?!/) [^*]* )*+ \*/
成功
/*aaaa**bbb***cc***
/
/\* [^*]* (?: \*+
(?!/)
[^*]* )*+ \*/
失败 >/*aaaa**bbb***cc***/
/\* [^*]*
(?: \*+(?!/) [^*]* )*+
\*/
失败
/*aaaa**bbb***
cc**
*/
/\* [^*]*
(?: \*+(?!/) [^*]* )*+
\*/
回溯
/*aaaa**bbb***cc**
*/
/\* [^*]* (?: \*+(?!/) [^*]* )*+
\*/
成功