1

优化?

我在使用以下正则表达式时遇到问题:

/^\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
4

1 回答 1

0

当您必须考虑字符串嵌入、转义和行延续时,解析 C/C++ 样式注释会稍微复杂一些。

这也需要一个单一的字符消耗传递方法(在检查完所有其他内容之后)。在这种情况下,在许多可能的匹配项中,您只对一项感兴趣——C 风格的注释/* */

因此,在全局搜索和大量匹配的情况下,只有一个让您感兴趣,比如捕获组 1 匹配。当然,在您的情况下,简单的替换不会削减它。

因此,您必须坐在全局查找(但不是替换)循环中。每个匹配项都将是源字符串的一部分,不会跳过任何部分,因此每个匹配项都将附加到目标字符串。

在循环期间,当捕获组 1 匹配(C 样式注释)时,您可以进行不那么简单的替换以使其成为 C++ 注释,然后将该结果附加到目标字符串。

这就是它的要点。如果这不能用您使用的任何语言完成,那么它就不能正确完成,这是肯定的!

以下是当您捕获 C 样式注释时执行转换的正则表达式列表//,它们必须按照出现的顺序执行(符号仅为 Perl 示例):

 # s{ ^  /\*     (?: [^\S\n] | \*)*       }{// }xmg;
 # s{ ^          (?: [^\S\n] | \*)* \*/ $ }{// }xmg;
 # s{ ^                                 $ }{// }xmg;
 # s{ ^          (?: [^\S\n] | \*)+       }{// }xmg;
 # s{ (?<![\s*]) (?: [^\S\n] | \*)+     $ }{}xmg;
 # s{ (?<![\s*]) (?: [^\S\n] | \*)* \*/ $ }{}xmg;

这是在您的查找循环中使用的正则表达式(如上所述)。这个正则表达式可以在任何 Perl 新闻组中找到,它是 FAQ 的一部分。

    # (?:(/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)|//(?:[^\\]|\\\n?)*?\n)|(?:"(?:\\[\S\s]|[^"\\])*"|'(?:\\[\S\s]|[^'\\])*'|[\S\s][^/"'\\]*)
    # -----------------------------------------------------------------


    (?:                             # Comments 

         (                               # (1 start)
              /\*                             # Start /* .. */ comment
              [^*]* \*+
              (?: [^/*] [^*]* \*+ )*
              /                               # End /* .. */ comment
         )                               # (1 end)
      |  
         //                              # Start // comment
         (?: [^\\] | \\ \n? )*?          # Possible line-continuation
         \n                              # End // comment
    )
 |  
    (?:                             # Non - comments 
         "
         (?: \\ [\S\s] | [^"\\] )*       # Double quoted text
         "
      |  '
         (?: \\ [\S\s] | [^'\\] )*       # Single quoted text
         ' 
      |  [\S\s]                          # Any other char
         [^/"'\\]*                       # Chars which doesn't start a comment, string, escape,
                                         # or line continuation (escape + newline)
    )
于 2013-10-11T08:55:23.203 回答