复杂的正则表达式与preg_replace,替换不在[和]内的单词

时间:2012-02-22 14:20:02

标签: php regex preg-replace

我无法找到正确的正则表达式来实现我想要的目标。

我有一句话:

Hi, my name is Stan, you are welcome, hello.

我希望改变它:

[hi|hello|welcome], my name is [stan|jack] you are [hi|hello|welcome] [hi|hello|welcome].

现在我的正则表达式已经完成了一半,因为有些单词没有被替换,被替换的单词正在删除一些字符

这是我的测试代码

<?php 

$test = 'Hi, my name is Stan, you are welcome, hello.';

$words = array(
    array('hi', 'hello', 'welcome'),
    array('stan', 'jack'),
);

$result = $test;
foreach ($words as $group) {
    if (count($group) > 0) {
        $replacement = '[' . implode('|', $group) . ']';
        foreach ($group as $word) {
            $result = preg_replace('#([^\[])' . $word . '([^\]])#i', $replacement, $result);
        }
    }
}

echo $test . '<br />' . $result;

任何帮助将不胜感激

3 个答案:

答案 0 :(得分:3)

您正在使用的正则表达式过于复杂。您只需要使用常规括号()来使用正则表达式替换:

<?php 

$test = 'Hi, my name is Stan, you are welcome, hello.';

$words = array(
        array('hi', 'hello', 'welcome'),
        array('stan', 'jack'),
        );

$result = $test;
foreach ($words as $group) {
    if (count($group) > 0) {
        $imploded = implode('|', $group);
        $replacement = "[$imploded]";
        $search = "($imploded)";
        $result = preg_replace("/$search/i", $replacement, $result);
    }
}

echo $test . '<br />' . $result;

答案 1 :(得分:1)

preg_replace 支持数组作为参数。无需循环迭代。

$s = array("/(hi|hello|welcome)/i", "/(stan|jack)/i");
$r = array("[hi|hello|welcome]", "[stan|jack]");
preg_replace($s, $r, $str); 

动态

$test = 'Hi, my name is Stan, you are welcome, hello.';
$s = array("hi|hello|welcome", "stan|jack");
$r = array_map(create_function('$a','return "[$a]";'), $s);
$s = array_map(create_function('$a','return "/($a)/i";'), $s);
echo preg_replace($s, $r, $str);
//[hi|hello|welcome], my name is [stan|jack], you are [hi|hello|welcome], [hi|hello|welcome].

答案 2 :(得分:1)

你的正则表达式:

'#([^\[])' . $word . '([^\]])#i'

也匹配$word之前和之后的一个字符。正如他们所做的那样,他们取而代之。所以你的替换字符串也需要引用这些部分:

'$1' . $replacement . '$2'

Demo