例如,以下代码使用<i>
标记包装每个匹配的字符。
echo preg_replace('/[aeiou]/', '<i>$0</i>', 'alphabet');
// result: <i>a</i>lph<i>a</i>b<i>e</i>t
但我希望它只能替换每个角色一次。
我正在寻找像<i>a</i>lphab<i>e</i>t
这样的结果,其中第二个a
没有标记,因为搜索字符串只有一个a
。
答案还应该允许两个或多个相同的字符,每个字符只能使用一次。例如,如果我在字符串aaeioo
中搜索alphabetsoupisgood
,则它应该与a
两个匹配,但只能匹配三个o
中的两个&{} #39; S
答案 0 :(得分:3)
如果你只想要一个字母只被替换一次,那么以下正则表达式应该有效:
echo preg_replace('/([aeiou])(?!.+?\\1)/', '<i>$1</i>', 'alphabet');
<强>输出:强>
alph<i>a</i>b<i>e</i>t
PS:请注意,它会替换最后一个字母而不是第一个字母。
修改强>
以下会产生与OP预期相同的输出(感谢@AntonyHatchkins):
echo strrev(preg_replace
('/([aeiou])(?!.+?\\1)/', strrev('<i>1$</i>'), strrev('alphabet')))."\n";
编辑2:
根据OP的评论:
Can you help me allow more than one a then? How can I match 2, but not 3 a's
我发布了这个答案:
echo strrev(preg_replace('/([aeiou])(?!(.+?\\1){2})/',
strrev('<i>1$</i>'), strrev('alphabetax'))) . "\n";
编辑3:
OP的另一个评论:
that will allow duplicates for all characters in the string, not just 2 a's & 1 e
我发布了这个答案:
echo strrev(preg_replace(array('/(a)(?!(.+?\\1){2})/',
'/(?<!>)([eiou])(?!.+?\\1)/'),
array(strrev('<i>1$</i>'), strrev('<i>1$</i>')), strrev('alphabetaxen')))."\n";
<强>输出:强>
<i>a</i>lph<i>a</i>b<i>e</i>taxen
注意:我认为原始问题已经改变了很多次,所以请不要在这个问题上增加更多的复杂性。如果您有不同的疑问,可以发布另一个问题。
答案 1 :(得分:0)
根据http://php.net/manual/es/function.preg-replace.php,您可以指定一个额外的参数来限制替换次数。
编辑:对不起,我最初没有得到您的问题。在那种情况下,它是不可能的。由于正则表达式的性质,它不知道它所取代的数量。我可能错了,但我怀疑是否存在正则表达式,每个字符只能替换一次。
你最好的选择是拨打5个电话,每个角色一个。像这样:
$res = preg_replace('/a/', '<i>$0</i>', 'alphabet', 1);
$res = preg_replace('/e/', '<i>$0</i>', 'alphabet', 1);
$res = preg_replace('/i/', '<i>$0</i>', 'alphabet', 1);
$res = preg_replace('/o/', '<i>$0</i>', 'alphabet', 1);
$res = preg_replace('/u/', '<i>$0</i>', 'alphabet', 1);
echo $res;
干杯
答案 2 :(得分:0)
使用
echo preg_replace('/[aeiou]/', ' ', 'alphabet', 1);
对不起,我在你编辑你的问题之前已经开始了
这个怎么样。
$word = "alphabet";
$replace = array('a','e','i','o','u');
$with = array('','','','','');
echo str_replace($replace,$with,$word); //lphbt
答案 3 :(得分:0)
丑陋,但这是一种方法。
echo
preg_replace('/a/','<i>$0</i>',
preg_replace('/e/','<i>$0</i>',
preg_replace('/i/','<i>$0</i>',
preg_replace('/o/','<i>$0</i>',
preg_replace('/u/','<i>$0</i>','alphabet',
1),1),1),1),1);
答案 4 :(得分:0)
这是使用preg_replace_callback()
功能的另一种方法,所以我将其作为一个全新的答案发布。
function replace_first($matches) {
static $used = array();
$key = $matches[0];
if (in_array($key,$used)) return $key;
$used[] = $key;
return '<i>' . $key . '</i>';
}
$str = preg_replace_callback('/[aeiou]/','replace_first','alphabet');
echo $str;
将输出<i>a</i>lphab<i>e</i>t
答案 5 :(得分:-1)
我能做的最好就是遍历每个角色。 (我尽可能避免循环)我希望有一种更清洁的方式,但现在这样做。
$word = 'alphabetsoupisgood';
$match = 'aaeou';
$wordArr = str_split($word);
$matchArr = str_split($capitals);
foreach ($matchArr as $c) {
$key = array_search($c, $wordArr);
if ($key !== false) {
$wordArr[$key] = strtoupper($c);
}
}
foreach ($wordArr as $k => $c) {
if (ctype_upper($c)) {
$wordArr[$k] = '<i>' . strtolower($c) . '</i>';
}
}
$word = implode('',$wordArr);
echo $word;
这是在键盘中但他们正在运行一些超级旧版本的PHP,因此ctype_upper
未启用... http://codepad.org/UoLWcK2S
如果有人可以使用preg_replace提供更清晰的答案,我很乐意将你的答案标记为答案。