我只是想知道如何为 preg_replace 应用多个规则,而不在第一次运行时执行它们。有点复杂,我举个例子来解释一下。
输入:
$string = 'The quick brown fox jumps over the lazy freaky dog';
规则:
- 将 a、i、o 替换为 u(如果不在单词开头且如果不在元音之前/之后)
- 将 e、u 替换为 i(如果不在单词开头且不在元音之前/之后)<
- 将 ea 替换为 i(如果不在单词开头)
- 将整个单词即 dog 替换为 cat,将 fox 替换为 wolf(不应用上述规则)里>
输出: 这只敏捷的棕色狼在这只活泼活泼的猫身上跳跃
我从这样的事情开始:(感谢 Ezequiel Muns 编辑)
$patterns = array();
$replacements = array();
$patterns[] = "/(?<!\b|[aeiou])[aio](?![aeiou])/";
$replacements[] = "u";
$patterns[] = "/(?<!\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变成fux
- 规则:将fux变为fix
如果角色已经受到前一个规则的影响,是否有办法避免以下规则?
这有道理吗?
最佳答案
首先,您需要明确替换条件,您的规则规定“不在单词开头且不在元音之前/之后”,但您尚未在正则表达式中实现这一点。您可以使用 Negative Lookahead/Lookbehind 来完成此操作。例如:
- 将 a、i、o 替换为 u(如果不在单词开头且不在元音之前/之后)
可以通过以下方式实现:
$patterns[] = "/(?<!\b|[aeiou])[aio](?![aeiou])/";
$replacements[] = "u";
该方法可用于实现前3条规则。
下一个问题是“fox”和“dog”将受到前 3 个规则的影响,因此您应该将更改版本替换为“wolf”和“cat”。所以对于狗=>猫:
$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 和 ()。
关于PHP preg_replace 多条规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3445018/