2
$string='print the imprint with the imprinted printing paper';

$pattern=array('/print/','/imprint/','/paper/',);
$replacement=array('imprint','print','machine');

输出:

print the imprint with the imprinted printing machine

我想我理解正确的是前两种模式相互覆盖。我正在考虑让这变得更加复杂,但 REGEX 对我来说仍然是巫术。显示输入字符串后,我想将其取回:imprint the print with the printed imprinting machine. 如果我也能看到如何让它输出imprint the print with the imprinted printing machine,那也很棒。

如果你能解释你的正则表达式,那会更有帮助。也许以后我可以自己做更多的事情。

4

2 回答 2

4

在一个正则表达式中完成所有这些替换,你很好,因为在一次替换中,正则表达式将在一次替换后继续,并且不会再次尝试与替换匹配:

$string = 'print the imprint with the imprinted printing paper';

// A single array of find => replace
$replacements = array( 
    'print'   => 'imprint', 
    'imprint' => 'print', 
    'paper'   => 'machine'
);

// Dynamically form the regex, properly escaping it
$delimiter = '/';
$words = array_keys( $replacements);
$regex = $delimiter . '\b(' . implode('|', array_map( 'preg_quote', $words, array_fill( 0, count( $words), $delimiter))) . ')\b' . $delimiter;

形成的正则表达式如下所示:

/\b(print|imprint|paper)\b/

在哪里:

  1. \b是单词边界。
  2. ()是一个捕获组。
  3. print|imprint|paper是或匹配其中一个词

最后,进行替换:

$result = preg_replace_callback( $regex, function( $match) use( $replacements) {
    return $replacements[$match[1]];
}, $string);
echo $result;

将输出

imprint the print with the printed imprinting machine
于 2013-07-08T21:04:53.597 回答
2

如果您需要进行直接的字符串替换,而不是多次重复结果字符串,您应该使用strtr()

strtr($string, array(
    'imprint' => 'print',
    'print' => 'imprint',
    'paper' => 'machine',
));

要替换的单词按字符串长度排序,最具体的在前。

注意:这当然不像正则表达式那样灵活,尤其是在只替换完整的单词时,即只有当它自己存在时/\bword\b/才会匹配;word这不是你可以strtr()和朋友一起做的事情。

使用正则表达式

preg_replace()仅对字符串执行一次传递,您需要将替换键组合成一个表达式,即

/imprint|print|paper/

此表达式使用交替,受搜索字符串之间的管道字符影响。要仅匹配整个单词,您需要添加边界匹配,这是一个\b匹配单词和非单词之间转换的特殊序列。

/\b(?:imprint|print|paper)\b/

这将匹配"imprint"但不匹配"pimprint"

如果您要沿着这条路线走,则需要使用preg_replace_callback();来执行替换。对于每个匹配,它都会执行一个自定义函数,您可以在其中确定用什么替换它。您需要为其创建一个替换地图,就像我在之前的strtr()示例中使用的那样。

$map = array(
    'imprint' => 'print',
    'print' => 'imprint',
    'paper' => 'machine',
);

$replacer = function($match) use ($map) {
    // $match[0] holds the found word
    return $map[$match[0]];
};

preg_replace_callback('/\b(?:imprint|print|paper)\b/', $string, $replacer);

让它充满活力

我手动创建了正则表达式,但为了使其灵活,您需要根据替换映射动态生成它。为此,我们需要:

  1. 从替换映射中提取键;
  2. 转义任何特殊字符;
  3. 构建最终表达式。

这是构建表达式的方式:

// step 1
$replacement_keys = array_keys($map);
// step 2
$escaped_keys = array_map(function($key) {
    return preg_quote($key, '/');
}, $replacement_keys);
// step 3
$pattern = '/\b(?:' . join('|', $escaped_keys) . ')\b/';
于 2013-07-08T21:06:24.647 回答