PHP preg_replace多个规则

时间:2010-08-09 23:48:30

标签: php preg-replace rules

我只是想知道如何在preg_replace中应用多个规则而不在第一次运行中执行它们。它有点复杂让我根据一个例子来解释。

输入:

$string = 'The quick brown fox jumps over the lazy freaky dog'; 

规则:

  • a i o 替换为 u (如果不是在单词的开头&如果不是在元音之前/之后)
  • e u 替换为 i (如果不是在单词的开头,如果不是在元音之前/之后)< / LI>
  • ea 替换为 i (如果不是在单词的开头)
  • 替换整个单词,即 dog wox 替换(不应用上述规则)< / LI>

输出:     这只快速的布鲁姆狼蹦蹦跳过这只慵懒的猫咪




我从这样的事情开始:( 编辑感谢Ezequiel Muns

$patterns = array();
$replacements = array();

$patterns[] = "/(?&lt;!\b|[aeiou])[aio](?![aeiou])/";
$replacements[] = "u";

$patterns[] = "/(?&lt;!\b|[aeiou])[eu](?![aeiou])/";
$replacements[] = "i";

$patterns[] = '/ea/';
$replacements[1] = 'i';

$patterns[] = '/dog/';
$replacements[0] = 'cat';

echo preg_replace($patterns, $replacements, $string);

输出

Thi qiick briwn fix jimps ivir thi lizy friiky dig



编辑:

正如您所看到的那样,问题是以前的规则会覆盖每条规则

示例' fox ':

  1. 规则:将狐狸变为 fux
  2. 规则:将 fux 变为修复
  3. 如果角色已经受到之前规则的影响,有没有办法避免以下规则?

    这有意义吗?

1 个答案:

答案 0 :(得分:3)

首先你需要明确更换条件,你的规则说'不是在一个单词的开头而不是在元音之前/之后',但你没有在正则表达式中实现它。你可以使用Negative Lookahead / Lookbehind来做到这一点。例如:

  1. 用你替换a,i,o(如果不是在一个单词的开头,如果不是在元音之前/之后)
  2. 可以通过以下方式实施:

    $patterns[] = "/(?<!\b|[aeiou])[aio](?![aeiou])/";
    $replacements[] = "u";
    

    此方法可用于实现前3条规则。

    接下来的问题是'狐狸'和'狗'会受到前3条规则的影响,因此您应该将已更改的版本替换为“狼”和“猫”。所以对于dog =&gt;猫:

    $patterns[] = "/\bdug\b/";
    $replacements[] = "cat";
    

    注意:由于preg_replace使用数组的方式,最好不要在$ patterns和$ replacements数组中使用索引,因为这些可能会产生误导。像我上面那样成对使用[]运算符,所以你总是知道什么是什么。

    第2部分:

    啊哈。我知道了。你需要更换替代品。

    您可以使用与第一种情况相匹配的正则表达式,这是有问题的情况。然后你可以使用preg_replace的一个有趣的奇怪功能:当你添加e修饰符时,替换字符串将被评估为PHP代码。将此与捕获组相结合,您可以根据匹配的内容决定是输出u还是i

    $patterns[] = "/(?<!\b|[aeiou])([aeiou])(?![aeiou])/e";
    $replacements[] = '("$1" == "e" || "$1" == "u")? "i":"u"';
    

    *注意元音匹配类周围的/ e和()。