【问题标题】:Removing Block Comments via Regex通过正则表达式删除块注释
【发布时间】:2011-05-11 13:29:57
【问题描述】:

我很难让这个正则表达式工作。我要做的就是删除块 cmets。这是我到目前为止所拥有的,但我无法摆脱最终的*/

$string = 'this is a test /*asdfa  */ ok then';

$pattern = '/\/\*([^\*\/]*)/i';

$replacement = '';

echo preg_replace($pattern, $replacement, $string);

//this is a test */ ok then

任何帮助将不胜感激。

【问题讨论】:

  • PHP 不是常规语言,因此无法解析它或使用正则表达式删除所有有效的块 cmets。
  • @Paul:你不能用正则表达式解析 PHP,但是你可以用词法分析它就好了。不需要一个成熟的解析器来摆脱 cmets(实际上,通常 cmets 在词法分析中被丢弃,而不是解析)
  • @Billy 不,你不能。 en.wikipedia.org/wiki/Chomsky_hierarchy
  • 我是第一个不鼓励将正则表达式用于他们无法处理的任务的人。但是 C 风格的注释 可以 被正则表达式识别(并且例如剥离),因为它们不能嵌套(这在 PHP 和其他很多地方都是一样的)。 /* a /* b */ echo 'see?'; */ 会“看到?” (或者更确切地说,解析器拒绝它是因为最终的 */,这仍然证明了这一点。顺便说一句,SO 语法突出显示正确。
  • 见这个例子" this is a comment /* or is it? */"。字符串中的注释是否应该被删除?想让它更复杂吗?引入一些heredoc。

标签: php regex


【解决方案1】:

试试这个作为你的模式:

/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/

【讨论】:

  • 我不明白... \r\n 在那里做什么?
  • 它删除新行。他给出的示例可能不需要,但这就是我用来删除多行 cmets 的方法。
  • @wajiw:为什么不让它匹配任何字符?我看不出换行符有什么特别之处。
  • 我遇到了 .* 与新行不匹配的问题
  • 是的,这是一种更聪明的做法 :-) 谢谢
【解决方案2】:

使用与/ 不同的分隔符——这会让人感到困惑。

'#/\*.+?\*/#s'怎么样;

【讨论】:

  • 那里应该有一个m 修饰符吗? (免责声明我对这里的多行正则表达式有点生疏。)
  • 你实际上需要s (DOT_ALL),而不是m
  • @Billy - 谢谢。这是我可以理解的,并且实际上适用于您想要摆脱 /*** a */ 的情况-其中一些答案不适用于这种情况。另外,我认为它的使用比分词器简单得多。
  • @Abs:1. 谢谢,2. 公平地说,分词器会更准确。 (但是,你已经知道了;))
【解决方案3】:

token_get_all 并在没有T_COMMENTs 的情况下重新构建它。我觉得没什么好说的了。

【讨论】:

  • 每个人都喜欢分词器。第二句也+1。
  • 矫枉过正的解决方案是矫枉过正。正则表达式对于 this 用例已经足够且更合适。 (并不是说标记器也不会在内部使用它们)
  • @mario 你知道分词器是如何工作的吗?正则表达式并不神奇......所以不要以为你可以在任何地方使用它们。
  • @Alin Purcaru:我没有对anywhere做出任何断言,而是明确表示“这个用例”。是的,我确实知道一些关于它们的事情,而且我还编写了一些标记器。
  • @mario 在特定条件下使用一些正则表达式来查找token与使用a正则表达式是不同的。
【解决方案4】:

/\*|\*/ 模式运行两次preg_replace 应该可以工作。

【讨论】:

  • 这只是去掉了注释分隔符,而不是注释文本本身。
【解决方案5】:

也许:

$pattern = '/\/\*([.]*)\*\//i';

请不要降价,因为这是一个快速猜测,试图提供帮助...... :)

【讨论】:

    【解决方案6】:

    为了修复你的主要模式,我可以告诉你,你不匹配最后的“*/”,因为你的模式中缺少它。

    按照你自己的模式,试试这个小修改:

    '/\/\*([^\*\/]*)**\*\/**/i'

    我还建议您使用不同的分隔符以使模式更易于阅读。

    #/\*([^\*/]*)\*/#i

    【讨论】:

      【解决方案7】:

      我正在使用这个(注意,/*...*/ cmets 只需要第一行):

        #-- extract /* ... */ comment block
        #  or lines of #... #... and //... //...
        if (preg_match("_^\s*/\*+(.+?)\*+/_s", $src, $uu)
        or (preg_match("_^\s*((^\s*(#+|//+)\s*.+?$\n)+)_ms", $src, $uu))) {
           $src = $uu[1];
        }
        // Public Domain, not CC
      

      效果很好。但与所有正则表达式解决方案一样,它会在 $PHP = "st/*rings" 边缘情况下失败。

      【讨论】:

      • 不要说“像所有正则表达式解决方案一样”,因为你错了。只说这里介绍的那些太原始了,不适合这项壮举。
      • @tchrist:我的错。在试图纠正对正则表达式的诽谤时,我自己过度概括了。
      猜你喜欢
      • 2013-06-25
      • 2015-07-24
      • 2011-01-28
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 2011-04-01
      • 2020-09-30
      相关资源
      最近更新 更多