Php 基于字符串中的位置替换
有没有一种方法可以使用正则表达式根据位置替换字符串中的字符 例如,我正在研究的一个项目的重写规则之一是“如果Php 基于字符串中的位置替换,php,regex,Php,Regex,有没有一种方法可以使用正则表达式根据位置替换字符串中的字符 例如,我正在研究的一个项目的重写规则之一是“如果o是倒数第二个元音且是偶数(从左到右计数),则将o替换为o。” 例如: heabatoik将变成heabatöik(o是倒数第二个元音,也是第四个元音) habatoik不会改变(o是倒数第二个元音,但是第三个元音) 在PHP中使用preg\u replace可以实现这一点吗?您可以使用将字符串拆分为元音/非元音部分并进行处理 e、 差不多 preg_match_all("/(([ae
o
是倒数第二个元音且是偶数(从左到右计数),则将o
替换为o
。”
例如:
将变成heabatoik
(heabatöik
是倒数第二个元音,也是第四个元音)o
不会改变(habatoik
是倒数第二个元音,但是第三个元音)o
preg\u replace
可以实现这一点吗?您可以使用将字符串拆分为元音/非元音部分并进行处理
e、 差不多
preg_match_all("/(([aeiou])|([^aeiou]+)*/",
$in,
$out, PREG_PATTERN_ORDER);
根据您的具体需要,您可能需要修改正则表达式中
()*+?
的位置。从主题字符串的开头开始,您希望匹配2n+1个元音,后跟一个o
,但前提是o
后跟一个元音:
$str = preg_replace(
'/^((?:(?:[^aeiou]*[aeiou]){2})*)' . # 2n vowels, n >= 0
'([^aeiou]*[aeiou][^aeiou]*)' . # odd-numbered vowel
'o' . # even-numbered vowel is o
'(?=[^aeiou]*[aeiou][^aeiou]*$)/', # exactly one more vowel
'$1$2ö',
'heaeafesebatoik');
要执行相同的操作,但对于奇数的o
,请匹配2n个前导元音,而不是2n+1:
如果其中一个不匹配,则不会执行替换,因此如果您正试图这样做,则可以安全地按顺序运行它们。我想详细介绍一下施密特。(我没有足够的分数来添加评论,我不是想抢他的风头)。我会使用标志
PREG\u OFFSET\u CAPTURE
,因为它不仅返回元音,而且还返回元音所在的位置。这是我的解决方案:
const LETTER = 1;
const LOCATION = 2
$string = 'heabatoik'
preg_match_all('/[aeiou]/', $string, $in, $out, PREG_OFFSET_CAPTURE);
$lastElement = count($out) - 1; // -1 for last element index based 0
//if second last letter location is even
//and second last letter is beside last letter
if ($out[$lastElement - 1][LOCATION] % 2 == 0 &&
$out[$lastElement - 1][LOCATION] + 1 == $out[$lastElement][LOCATION])
substr_replace($string, 'ö', $out[$lastElement - 1][LOCATION]);
注:
我会这样做:
$str = 'heabatoik';
$vowels = preg_replace('#[^aeiou]+#i', '', $str);
$length = strlen($vowels);
if ( $length % 2 && $vowels[$length - 2] == 'o' ) {
$str = preg_replace('#o([^o]+)$#', 'ö$1', $str);
}
为什么最后一个
+
是[^aeiou]+
而不是*
?我以为我看得太多了!:)+1表示风格,但说真的,我永远不想保持这种风格谢谢,你能告诉我,如果输入字符串较长,为什么字符串的第一部分会被截断heeafesebatoik
给了我fesebatöik
谢谢你,如果我想为奇数做这件事,而不与偶数正则表达式冲突,我该怎么办?
print_r(preg_match_all('/[aeiou]/', 'heabatoik', $in, $out, PREG_OFFSET_CAPTURE));
Array
(
[0] => Array
(
[0] => Array
(
[0] => e
[1] => 1
)
[1] => Array
(
[0] => a
[1] => 2
)
[2] => Array
(
[0] => a
[1] => 4
)
[3] => Array
(
[0] => o
[1] => 6
)
[4] => Array
(
[0] => i
[1] => 7
)
)
)
$str = 'heabatoik';
$vowels = preg_replace('#[^aeiou]+#i', '', $str);
$length = strlen($vowels);
if ( $length % 2 && $vowels[$length - 2] == 'o' ) {
$str = preg_replace('#o([^o]+)$#', 'ö$1', $str);
}