我正在尝试使用preg_replace
将数字更改为字母,但只包含""
中包含的数字,并且子字符串中的数字不超过7个字符。
示例输入字符串:
"3"sca"""co"1"str"0"ctor""r"3"t"0"r"1""locat"5"o"133""0"27""754a49b393c2a0"33"b97"332"cb7"3"c3c07"2""co"1"str"0"ctor""r"3"t"0"
期望的效果是每个符合条件的2
成为d
,并且每个符合条件的3
成为e
。
这些是正确替换的例子:
"3"
变为e
"23"
变为de
"33"
变为ee
"32"
变为de
"333223"
变为eeedde
我的编码尝试:
$string = preg_replace("/\"322\"+/", "edd", $string);
$string = preg_replace("/\"233\"+/", "dee", $string);
$string = preg_replace("/\"32\"+/", "ed", $string);
$string = preg_replace("/\"23\"+/", "de", $string);
$string = preg_replace("/\"33\"+/", "e", $string);
$string = preg_replace("/\"333\"+/", "e", $string);
$string = preg_replace("/\"3\"+/", "e", $string);
$string = preg_replace("/\"3\"+/", "e", $string);
$string = preg_replace("/\"3\"+/", "e", $string);
$string = preg_replace("/\"3\"+/", "e", $string);
$string = preg_replace("/\"3\"+/", "e", $string);
如何使用一个preg_replace调用进行所有符合条件的替换?
答案 0 :(得分:1)
要仅替换引号内的2和3,您可以执行preg_replace_callback()
来完成此操作。
$before = '754a49b393c2a0"33"b97"332"cb7"3"c3c07"2"';
$after = preg_replace_callback(
'/"([^"]+)"/',
function ($matches) {
return str_replace( array( '2', '3' ), array( 'd', 'e' ), $matches[1] );;
},
$before
);
echo $after;
答案 1 :(得分:0)
使用此正则表达式在双引号之间找到2
或3
1到7次
(?<=\")[23]{1,7}(?=\")
“233223322”不会被“deeddeedd”替换,因为它有超过7个字符(9)
<强>解释强>
[23]{1,7}
2
或3
1至7次
(?<=\")
以双引号之前
(?=\")
后跟双引号
<强>段强>
$text = '"3"sca"""co"1"str"0"ctor""r"3"t"0"r"1""locat"5"o"133""0"27""754a49b393c2a0"33"b97"332"cb7"3"c3c07"2""co"1"str"0"ct"233223322"or""r"3"t"0"';
$regex = '/(?<=\")[23]{1,7}(?=\")/';
$text = preg_replace_callback($regex,
function ($m) {
switch ($m[0]) {
case '2': return 'd';
case '3': return 'e';
// Add other cases here ...
}
},
$text
);
echo $text;
答案 2 :(得分:0)
首先,我建议的代码。然后回顾一下本页采用的技术。
代码:(Demo)
echo preg_replace_callback('/"([23]{1,7})"/',
function ($m) {
return str_replace(['2', '3'], ['d', 'e'], $m[1]);
},
$text
);
Stephane Janicaud和BA_Webimax的preg_replace_callback()
答案在执行过程中有很好的组件和不太好的组件,但一般的逻辑是合理的。我会花一点时间来隔离一些弱点/机会并提供一些改进。
Stephane的模式:/(?<=\")[23]{1,7}(?=\")/
误解了问题,并在输入字符串中留下双引号。他编写了最合适的字符类和量词表达式(一到七次出现),但外观对模式效率造成了不必要的沉重负担;另外,双引号前的反斜杠是不必要的。这种模式在一个惊人的407 steps中评估OP的输入字符串。
接下来是对BA_Webimax模式的改编。他发布的模式不能提供仅定位2
和3
的所需精确度,而是提供任何非双引号字符。对于此比较,我将使用~"([23]{1,7})"~
。这是一个非常整洁有效的模式 - 没有使用外观,唯一的阻力是捕获组。此模式以可敬的142 steps评估字符串。
因为Stephane将一到七个字符传递给匿名函数并且switch
个案例只检查2
或3
的完全匹配,所以他的答案结束了根除第3和第4场比赛。这使答案完全错误。 (Add other cases
评论对于开发人员来说代码不合理yatta yatta
- 为什么要这样做?)
BA_Webimax使用str_replace()
对第一个捕获组字符串执行智能,直接,高效的操作。
我使用输入字符串检查了3v4l.org和str_replace()
在php7.2上的strtr()
的性能速度。也就是说,执行一个真正的基准测试将涉及更大量的输入数据 - 我只是没有沿着这条路走下去。
单功能替换:
str_replace(['2', '3'], ['d', 'e'], $m[1]);
strtr($m[1], ['2' => 'd', '3' => 'e']);