2

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

输入:

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

规则:

  • a , i , o替换为u(如果不是在单词的开头,如果不是在元音之前/之后)
  • eu替换为i(如果不是在单词的开头,如果不是在元音之前/之后)
  • ea替换为i(如果不是在单词的开头)
  • 替换整个词 ie dogwolf替换fox(不应用上述规则)

输出: 这只快速的棕色狼跃过这只 luzy friky 猫




我从这样的事情开始:(编辑感谢 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



编辑:

如您所见,问题在于每条规则都被前一条规则覆盖

示例“狐狸”:

  1. 规则:把狐狸变成狐狸
  2. 规则:将fux变成fix

如果角色已经受到上一条规则的影响,有没有办法避免以下规则?

这有意义吗?

4

1 回答 1

3

首先,您需要明确替换条件,您的规则说“不在单词开头,也不在元音之前/之后”,但您尚未在正则表达式中实现这一点。您可以使用 Negative Lookahead/Lookbehind 来做到这一点。例如:

  1. 将 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 代码。将此与捕获组相结合,它将允许您根据匹配的内容决定是输出 au还是输出 an 。i

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

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

于 2010-08-10T00:18:47.607 回答