如何用特定字母替换特定数字(在长度限制内)?
How to replace specific numbers (within a length limit) with specific letters?
我正在尝试使用 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 呼叫完成所有符合条件的替换?
要仅替换引号内的那些 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;
使用此正则表达式在双引号之间查找 2
或 3
1 到 7 次
(?<=\")[23]{1,7}(?=\")
"233223322" won't be replaced with "deeddeedd" because it has more than 7 characters (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;
首先,我建议的代码。然后回顾本页所采用的技术。
代码:(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()
答案在执行中有好的部分和不太好的部分,但总体逻辑是合理的。我将花一些时间来隔离一些 weakness/opportunities 并提供一些改进。
关于模式:
Stephane 的模式:/(?<=\")[23]{1,7}(?=\")/
误解了问题并在输入字符串中留下了双引号。他写了最合适的字符 class 和量词表达式(出现一到七次),但环视对模式效率造成了不必要的沉重负担;另外,双引号前的反斜杠是不必要的。此模式以惊人的 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']);
我正在尝试使用 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 呼叫完成所有符合条件的替换?
要仅替换引号内的那些 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;
使用此正则表达式在双引号之间查找 2
或 3
1 到 7 次
(?<=\")[23]{1,7}(?=\")
"233223322" won't be replaced with "deeddeedd" because it has more than 7 characters (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;
首先,我建议的代码。然后回顾本页所采用的技术。
代码:(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()
答案在执行中有好的部分和不太好的部分,但总体逻辑是合理的。我将花一些时间来隔离一些 weakness/opportunities 并提供一些改进。
关于模式:
Stephane 的模式:/(?<=\")[23]{1,7}(?=\")/
误解了问题并在输入字符串中留下了双引号。他写了最合适的字符 class 和量词表达式(出现一到七次),但环视对模式效率造成了不必要的沉重负担;另外,双引号前的反斜杠是不必要的。此模式以惊人的 407 steps.
接下来是对 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']);