2010-08-09 68 views
2

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

输入:

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

规则:

  • 更换一个Øü(如果不是在一个单词的开头如果不是,则为& E /后元音)
  • 更换ēü(如果不是在一个字&如果没有开始前/后元音)
  • 更换EA (如果不是在一个单词的开头)
  • 更换整个单词,即狐狸w^OLF(不应用上述规则)

输出: 氏快速bruwn狼jimps超过THI luzy friky猫




我开始用类似的东西:(编辑感谢埃塞基耶尔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. 规则:原来狐狸FUX
  2. 规则:原来FUX修复

是否有办法如果角色是,则避免以下规则已经受到以前规则的影响?

这有道理吗?

+0

'freaky'从哪里来? Pfft。我想要一个正则表达式使它成为正确的短语:P – 2010-08-10 00:00:52

回答

3

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

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

  1. (前一个单词&如果不是一开始如果不是/元音后)替换,I,O用U

可与实现

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

接下来的问题是,'狐狸'和'狗'将受到前3条规则的影响,所以你应该将更改版本更换为'狼'和'猫'。所以对于狗=>猫:

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

注:因为工作的preg_replace使用数组的方式,更好的做法是在$模式和$替换阵列不使用索引,因为这些可能会产生误导。像上面那样使用[]运算符,所以你总是知道什么是什么。

第2部分:

Aha。我懂了。你需要让替代品变得非常简单。

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

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

*请注意元音匹配类中的/ e和()。

+0

感谢兄弟,这就像魅力。 :) 但请看看我上面编辑过的帖子。 – Mayko 2010-08-10 01:58:20

+0

呵呵另一件事,你需要确保你也在你的'/ ea /'中使用了lookbehind,因为你说*不是在一个词的开头*。 – 2010-08-11 08:38:29

+0

你真了不起!非常感谢 – Mayko 2010-08-19 05:22:32