Preg_replace:“foo”,“bar”,“foo bar”和“bar foo”

时间:2013-01-13 16:04:17

标签: php html regex

我使用正则表达式来查找某些单词,并使用单词/字符串执行某些操作。

我的例子:

我不想用我找到的所有单词设置<strong>标记:

$string = 'Hello, there is foo, after there is bar but now I need foo bar.'

$html = preg_replace('/(foo|bar)/', '<strong>$1</strong>', $string);

$html will be 'Hello, there is <strong>foo</strong>, after there is <strong>bar</strong> but now I need <strong>foo</strong> <strong>bar</strong>.'

我不想,如果他们在搜索到另外一个单词之后是1个单词,那么结果是:

'Hello, there is <strong>foo</strong>, after there is <strong>bar</strong> but now I need <strong>foo bar</strong>.'

如何修改我的正则表达式以获取我们之间的2个单词并在不使用分隔标记的情况下处理它?<​​/ p>

由于

3 个答案:

答案 0 :(得分:2)

$search = 'foo bar blah';
$string = 'Hello, there is foo, after there is bar but now I need foo bar blah.';

$search = preg_quote($search);
$regex = $search . '|' . str_replace(' ', '|', $search);

$html = preg_replace('/\b(' . $regex . ')\b/', '<strong>$1</strong>', $string);

echo $html; // Outputs: Hello, there is <strong>foo</strong>, after there is <strong>bar</strong> but now I need <strong>foo bar blah</strong>.

答案 1 :(得分:1)

我们在这里:

$html = preg_replace('/(foo|bar)( (foo|bar))*/', '<strong>$0</strong>', $string);

可读性较低但效率稍高(非捕获组):

$html = preg_replace('/(?:foo|bar)(?: (?:foo|bar))*/', '<strong>$0</strong>', $string);

也许有一个解决方案,不重复(foo|bar) ...

哈,如果你不想在“arfooo”中匹配,不要忘记\b或类似的东西; - )


编辑:如果你需要更有活力的东西,感谢神秘ツ的想法:

$words = array('foo', 'bar');

// require PHP 5.3, not very efficient code
$escaped_words = array_map(function ($word) {
    return preg_quote($word, '/');
}, $words);

$pattern = '(?:' . implode('|', $escaped_words) . ')';

$html = preg_replace('/'.$pattern.'(?: '.$pattern.')*/', '<strong>$0</strong>', $string);

答案 2 :(得分:0)

$string = 'Hello, there is foo, after there is bar but now I need foo bar.';
$string.= ' Lets throw a bar foo in there as well!';

$html = preg_replace('/(bar foo|foo bar|foo|bar)/', '<strong>$1</strong>', $string);

echo $html;