Php 如何使preg_replace仅替换匹配的*每个*字符中的第一个?
例如,以下代码使用Php 如何使preg_replace仅替换匹配的*每个*字符中的第一个?,php,regex,string,preg-replace,Php,Regex,String,Preg Replace,例如,以下代码使用标记包装每个匹配字符 echo preg_replace('/[aeiou]/', '<i>$0</i>', 'alphabet'); // result: <i>a</i>lph<i>a</i>b<i>e</i>t echo preg_替换('/[aeiou]/'、'$0'、'alphabet'); //结果:字母表 但我希望每个字符只替换一次 我正在寻找一个类似于字母表的结果
标记包装每个匹配字符
echo preg_replace('/[aeiou]/', '<i>$0</i>', 'alphabet');
// result: <i>a</i>lph<i>a</i>b<i>e</i>t
echo preg_替换('/[aeiou]/'、'$0'、'alphabet');
//结果:字母表
但我希望每个字符只替换一次
我正在寻找一个类似于字母表的结果,其中第二个a
没有标记,因为搜索字符串只有一个a
你能帮忙吗?这是否可能在不遍历foreach循环中的每个字符的情况下实现
答案还应允许两个或多个相同的字符,每个字符只使用一次。例如,如果我在字符串alphabetsoupisgood
中搜索aaeioo
,它应该匹配a
,但只匹配三个o
中的两个。根据,您可以指定一个额外的参数来限制执行的替换量
编辑:对不起,我最初没有收到你的问题。在这种情况下,这是不可能的。由于Regex的性质,它不知道替换的数量。虽然我可能错了,但我怀疑是否存在一个正则表达式,它对每个字符只进行一次替换
你最好打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;
$res=preg_replace(“/a/”、“$0”、“字母表”、“1”);
$res=preg_replace(“/e/”、“$0”、“字母表”、“1”);
$res=preg_replace(“/i/”、“$0”、“字母表”、“1”);
$res=preg_replace(“/o/”、“$0”、“字母表”、“1”);
$res=preg_replace(“/u/”、“$0”、“字母表”、“1”);
echo$res;
干杯使用
echo preg_replace('/[aeiou]/', ' ', 'alphabet', 1);
抱歉,在您编辑问题之前我回答了您的问题
这个怎么样
$word = "alphabet";
$replace = array('a','e','i','o','u');
$with = array('','','','','');
echo str_replace($replace,$with,$word); //lphbt
丑陋,但这里有一个方法
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);
echo
preg_replace(“/a/”,“$0”,
preg_replace(“/e/”,“$0”,
preg_replace(“/i/”,“$0”,
preg_replace(“/o/”,“$0”,
preg_replace(“/u/”、“$0”、“字母表”,
1),1),1),1),1);
如果您只希望一个字母被替换一次,那么下面的正则表达式应该可以工作:
echo preg_replace('/([aeiou])(?!.+?\\1)/', '<i>$1</i>', 'alphabet');
编辑3:
alph<i>a</i>b<i>e</i>t
<i>a</i>lph<i>a</i>b<i>e</i>taxen
根据OP的另一位评论:
允许字符串中的所有字符重复,而不仅仅是2个a和1个e
我发布以下答案:
echo strrev(preg_replace('/([aeiou])(?!(.+?\\1){2})/',
strrev('<i>1$</i>'), strrev('alphabetax'))) . "\n";
echo strrev(preg_replace(array('/(a)(?!(.+?\\1){2})/',
'/(?<!>)([eiou])(?!.+?\\1)/'),
array(strrev('<i>1$</i>'), strrev('<i>1$</i>')), strrev('alphabetaxen')))."\n";
echo strrev(preg_replace(数组)('/(a)(?!(.+?\\1){2})/”,
“/(?)([eiou])(?!.+?\\1)/”,
数组(strev('1$)、strev('1$)、strev('alphabetaxen'))。“\n”;
输出:
alph<i>a</i>b<i>e</i>t
<i>a</i>lph<i>a</i>b<i>e</i>taxen
alphabetaxen
注意:我相信原来的问题已经改变了很多次,所以请不要在这个问题上增加更多的复杂性。如果您有不同的疑问,您可以自由发布另一个问题。这里有另一种使用该功能的方法,因此我将此作为全新的答案发布
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;
function replace_first($matches){
静态$used=array();
$key=$matches[0];
if(在数组中($key,$used))返回$key;
$used[]=$key;
返回“.$key.”;
}
$str=preg_replace_回调('/[aeiou]/'、'replace_first'、'alphabet');
echo$str;
将输出字母表
我能做的最好的事情就是循环遍历每个字符。(我尽量避免循环)我希望有一个更干净的方法,但现在就可以了
$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;
$word='alphabetsoupisgood';
$match='aaeou';
$wordArr=str_split($word);
$matchArr=str_分割(大写);
foreach($matchArr作为$c){
$key=array\u search($c,$wordArr);
如果($key!==false){
$wordArr[$key]=strtoupper($c);
}
}
foreach($wordArr为$k=>$c){
如果(c类以上($c)){
$wordArr[$k]=''.strtolower($c.'';
}
}
$word=内爆(“”,$wordArr);
回声$字;
在这里,它位于代码板中,但他们正在运行一些超旧版本的PHP,因此ctype\u upper
未启用
如果有人能用preg_replace提供一个更清晰的答案,我很乐意将你的答案标记为答案。关闭,但它不允许preg_replace继续在最后替换e
。结果只有lphabet
,而不是lphabt
。Close,但此方法不允许preg\u replace继续在最后替换e
。结果只有lphabet
,而不是lphabt
。不完全一样。起初我很乐观,但随后的preg_替换也包括了标签。请参见strrev(preg_replace('/([aeiou])(?!.+?\\1)/,“$1”,strrev('alphabet'))
将使其成为第一个one@AntonyHatchkins:很好,但是它给出了这个输出tebahpla
注意第二个strrev:echo strrev(preg_replace('/([aeiou])(?!.+?\\1)/',strev('1$'),strrev('alphabet'))
给出字母表
@AntonyHatchkins:非常感谢您的评论,我更新了我的答案。如果搜索字符串中没有重复字符,这会起作用。但是如果搜索字符串是aa
,它将失败。请参见是,但是如果搜索字符串是aa
,它将错过字母表中的第二个a
。请参见当然,因为这是您所要求的,并且正则表达式字符范围,例如/[abc]/
和/[aaaaaaaa bc]/
是相同的。如果您愿意更改方法,则可能需要更改方法。这非常接近,但如果搜索字符串中有多个相同的字符,则将失败。请参见此处仅使用“~(?)您的字母(?)在每个模式中,~'
而不是'/YOUR_LETTER_HERE/'
。额外信息:模式的第一部分说“前面不加
”,最后一部分说“后面不加
”。我和你有同样的感受。出于某种原因,下层选民不会花任何时间解释原因:/