正则表达式与字边界匹配太松散

时间:2013-10-25 23:20:51

标签: php regex

我有以下代码,我正在尝试使用单词边界匹配特定单词,用“censored”替换它们然后重建文本但由于某种原因正则表达式捕获尾随斜杠。为了清晰起见,我已简化为以下测试用例

<?php

$words = array('bad' => "censored");
$text = "bad bading testbadtest badder";
$newtext = "";

foreach( preg_split( "/(\[\/?(?:acronym|background|\*)(?:=.+?)?\]|(^|\W)bad(\W|$))/i", $text, null, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY ) as $section )
{
    if ( isset( $words[ $section ] )  )
    {
        $newtext .= $words[ $section ];
    }
    else
    {
        $newtext .= $section ;
    }
}

var_dump($newtext);

出口;

在这个例子中,我希望匹配“坏”,但不要使用标记testbadtest或badder。问题是“坏”(注意尾随空格)是匹配的,它不是$ words数组中的键。

有人可以解释我可能出错的地方吗?

提前致谢

1 个答案:

答案 0 :(得分:0)

我想我会采取不同的方法,因为我不确定你为什么使用preg_split()并在正则表达式中对你的删失词进行硬编码。

只需构建一个要替换的模式数组及其替换项,然后使用preg_replace()

// note no space in words or their replacements
$word_replacement_map = array(
    'bad' => 'b*d',
    'alsobad' => 'a*****d'
);
$bad_words = array_keys($word_replacement_map);
$patterns = array_map(function($item) {
    return '/\b' . preg_quote($item) . '\b/u';
}, $bad_words);
$replacements = array_values($replacement_map);
$input_string = 'the string with bad and alsobad words';
$cleaned_string = preg_replace($patterns, $replacements, $input_string);
var_dump($cleaned_string); // the string with b*d and a*****d words

请注意,如果您不需要特定于字词的替换,您可以将其简化为:

// note no space in words
$bad_words = array(
    'bad',
    'alsobad'
);
$replacement = 'censored';
$patterns = array_map(function($item) {
    return '/\b' . preg_quote($item) . '\b/u';
}, $bad_words);
$input_string = 'the string with bad and alsobad words';
$cleaned_string = preg_replace($patterns, $replacement, $input_string);
var_dump($cleaned_string); // the string with censored and censored words

请注意,我在正则表达式模式中使用字边界,这通常应该满足您的需求。