正则表达式匹配分号,但不在注释或引号中匹配

Regex match semicolon but not in comments or quotes

本文关键字:注释 正则表达式      更新时间:2023-09-26

我想使用正则表达式测试来返回所有匹配的分号,但前提是它们在引号(嵌套引号)之外,而不是注释代码。

testfunc();
testfunc2("test;test");
testfunc3("test';test");
testfunc4('test";test');
//testfunc5();
/* testfunc6(); */
/*
  testfunc7();
*/
/*
  //testfunc8();
*/
testfunc9("test'"test");

正则表达式字符串只应返回每个示例末尾的分号。

我一直在玩下面的方法,但它在示例 testfunc3 和 testfun9 上失败了。它也不会忽略评论...

/;(?=(?:(?:[^"']*+["']){2})*+[^"']*+'z)/g

任何帮助将不胜感激!

没有时间将其转换为 JS。这是Perl示例中的正则表达式,该正则表达式将与JS一起使用。

C 注释,

双/单字符串引号 - 取自 Jeffrey Friedl 的"strip C 注释",后来由 Fred Curtis 修改,改编为包括C++注释和目标分号(由我)。

捕获组 1(可选),包括所有分号,组 2 是分号(但可以是任何内容)。

修饰符是//xsg。

下面的正则表达式用于替换运算符 s/pattern/replace/xsg (即:替换为 $1[$2])。

我认为您的帖子只是为了了解是否可以做到这一点。如果您真的需要,我可以包含一个注释的正则表达式。

$str = <<EOS;
testfunc();
testfunc2("test;test"); 
testfunc3("test';test");
testfunc4('test";test');
//testfunc5();
/* testfunc6(); */
/*
  testfunc7();
*/
/*
  //testfunc8();
*/
testfunc9("test'"test");
EOS
$str =~ s{
     ((?:(?:/'*[^*]*'*+(?:[^/*][^*]*'*+)*/|//(?:[^'']|'''n?)*?'n)|(?:"(?:''.|[^"''])*"|'(?:''.|[^'''])*'|.[^/"''';]*))*?)(;)
 }
 {$1'[$2']}xsg;
print $str;

输出

testfunc()[;]
testfunc2("test;test")[;]
testfunc3("test';test")[;]
testfunc4('test";test')[;]
//testfunc5();
/* testfunc6(); */
/*
  testfunc7();
*/
/*
  //testfunc8();
*/
testfunc9("test"test")[;]

扩展了评论

 (  ## Optional non-greedy, Capture group 1
   (?:
      ## Comments
        (?:
            /'*         ##  Start of /* ... */ comment
            [^*]*'*+    ##  Non-* followed by 1-or-more *'s
            (?:
                [^/*][^*]*'*+
            )*          ##  0-or-more things which don't start with /
                        ##    but do end with '*'
            /           ##  End of /* ... */ comment
          |  
            //          ## Start of // ... comment
            (?:
                [^'']         ## Any Non-Continuation character ^'
              |               ##   OR
                '''n?         ## Any Continuation character followed by 0-1 newline 'n
             )*?            ## To be done 0-many times, stopping at the first end of comment
             'n         ##  End of // comment
        )
     | ##  OR,  various things which aren't comments, group 2:
        (?:
            " (?: ''. | [^"''] )* "  ## Double quoted text
          |
            ' (?: ''. | [^'''] )* '  ## Single quoted text
          |
            .           ##  Any other char
            [^/"''';]*  ##  Chars which doesn't start a comment, string, escape
        )               ##  or continuation (escape + newline) AND are NOT semi-colon ;
   )*?
 )
  ## Capture grou 2, the semi-colon
 (;)

这将适用于所有示例,但这取决于您要将其应用于的代码与示例的接近程度:

;(?!'S|(?:[^;]*'*/))

; - 匹配分号

(?! - 负面展望 - 确保 ->

'S - 分号后没有非空格字符

|(?:[^;]*'*/)) - 如果有空格字符,请确保直到下一个;都没有*/符号

如果您遇到任何问题,请告诉我。

如果这是你想使用的东西,

那么使用正则表达式没有害处,但如果这是你可能想重用的东西,以后正则表达式可能被证明不是最可靠的工具。

编辑:

修复第 5 号 - 现在分号将位于第一个匹配组中:

^(?:[^/]*)(;)(?!'S|(?:[^;]*'*/))