Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何使preg_replace仅替换匹配的*每个*字符中的第一个?_Php_Regex_String_Preg Replace - Fatal编程技术网

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/'
。额外信息:模式的第一部分说“前面不加
”,最后一部分说“后面不加
”。我和你有同样的感受。出于某种原因,下层选民不会花任何时间解释原因:/