使用正则表达式在注释块中查找和替换(部分)字符串

时间:2013-08-05 19:49:12

标签: php regex preg-replace

我正在尝试查找可能出现在注释块中的某个字符串。该字符串可以是一个单词,但它也可以是单词的一部分。例如,假设我正在寻找单词“codex”,那么这个单词应该用“bindex”替换,但即使它是单词的一部分,比如“codexing”。这应该改为“bindexing”。

诀窍是,只有当这个词在评论块中时,才会发生这种情况。

/* Lorem ipsum dolor sit amet, codex consectetur adipiscing elit. */

This word --> codex should not be replaced

/* Lorem ipsum dolor sit 
 * amet, codex consectetur 
 * adipiscing elit. 
 */

/** Lorem ipsum dolor sit 
 * amet, codex consectetur 
 * adipiscing elit. 
 */

// Lorem ipsum dolor sit amet, codex consectetur adipiscing elit.

# Lorem ipsum dolor sit amet, codex consectetur adipiscing elit.

------------------- Below "codex" is part of a word -------------------

/* Lorem ipsum dolor sit amet, somecodex consectetur adipiscing elit. */

/* Lorem ipsum dolor sit 
 * amet, codexing consectetur 
 * adipiscing elit. 
 */

And here also, this word --> codex should not be replaced

/** Lorem ipsum dolor sit 
 * amet, testcodexing consectetur 
 * adipiscing elit. 
 */

// Lorem ipsum dolor sit amet, __codex consectetur adipiscing elit.

# Lorem ipsum dolor sit amet, codex__ consectetur adipiscing elit.

到目前为止我的代码是:

$text = preg_replace ( '~(\/\/|#|\/\*).*?(codex).*?~', '$1 bindex', $text);

正如你所看到的in this example,这并不是我想要的方式。当它在多行/* */注释块中时,它不会替换该词,有时它也会删除“codex”一词前面的所有文本。

如何改进我的正则表达式以满足我的要求?

5 个答案:

答案 0 :(得分:3)

由于您在这里处理多行文本,因此您应该使用s修饰符(DOTALL)来匹配多行文本。也不需要转义正斜杠。

试试这段代码:

$text = preg_replace ( '~(//|#|/\*).*?(codex).*?~s', '$1 bindex', $text );

答案 1 :(得分:2)

$text = preg_replace ( '~(//|#|/\*)(.*?)(codex).*?~s', '$1$2bindex', $text );

这不会删除'codex'之前的评论,如anubhava的回答

答案 2 :(得分:1)

此版本可以处理任何类型的评论,并且不会因此类字符串/**/ codex /**//*xxxx codex codex xxxx*/而失败:

$pattern = <<<'LOD'
~
# definitions
(?(DEFINE)
    (?<cl> (?> [^c\n]++ | c(?!odex) )++            )
    (?<c>  (?> [^*c]++ | \*++(?!/) | c(?!odex) )++ )
)

# pattern
(?|
    (?> (?>//|\#) \g<cl>*+ | \G(?<!^) \g<cl>?+ ) \K codex (\g<cl>*+)
  |
    (?> /\* \n*+ | \G(?<!^) (?!\n) ) \g<c>*+ \K codex (\n*+) 
)  
~x
LOD;
$replacement ="bindex$3";
$result = preg_replace($pattern, $replacement, $subject);

答案 3 :(得分:0)

使用子组的这样的东西应该可以工作;

$str = preg_replace(
    '~(<!--[a-zA-Z0-9 \n]*)(MYWORD)([a-zA-Z0-9 \n]*-->)~s',
    '$1$3',
     $input
);

您只需要为每种类型的注释创建一个单独的规则,并使用字符类限制注释中允许的可能字符(您可能更喜欢使用否定的字符类)。

答案 4 :(得分:0)

正如在不同的评论中写过数百,数千甚至数百万次之前,正则表达式 NOT 用于解析代码或在一个中搜索错误。

请考虑以下示例:

// code to be replaced
var a = "/*code to be replaced*/";

/* code to be replaced
var b = "*/code to be replaced"; */

使用REGEX无法解析代码(是的,通过注释来查找字符串是否在于注释块内)。

找到一个解析器库,或创建一个自己的缩减库。如果您确实创建了一个,请记住脚本的所有不同用例,特别是字符串将如何影响您的代码。