[英]How to replace specific numbers (within a length limit) with specific letters?
I am trying to use preg_replace
to change numbers to letters, but only numbers wrapped in ""
and not more than 7 characters in the substring. 我正在尝试使用
preg_replace
将数字更改为字母,但仅将数字包装在""
并且子字符串中的字符数不得超过7个。
Sample input string: 输入字符串示例:
"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"
The desired effect is for every qualifying 2
to become d
and every qualifying 3
to become e
. 期望的效果是每个合格
2
变为d
,每个合格3
变为e
。
These are examples of correct replacements: 这些是正确替换的示例:
"3"
becomes e
"3"
变成e
"23"
becomes de
"23"
变成de
"33"
becomes ee
"33"
成为ee
"32"
becomes de
"32"
变成de
"333223"
becomes eeedde
"333223"
成为eeedde
My coding attempt: 我的编码尝试:
$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);
How can I make all qualifying replacements with one preg_replace call? 如何通过一次preg_replace调用进行所有合格替换?
To only replace those 2s and 3s inside quotes, you can do a preg_replace_callback()
to accomplish that. 要只替换引号内的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;
Use this regex to find either 2
or 3
between double-quotes from 1 to 7 times 使用此正则表达式可在1到7次的双引号之间找到
2
或3
(?<=\\")[23]{1,7}(?=\\")
"233223322" won't be replaced with "deeddeedd" because it has more than 7 characters (9)
“ 233223322”不会替换为“ deededed”,因为它具有7个以上的字符(9)
Explanation 说明
[23]{1,7}
Either 2
or 3
from 1 to 7 times [23]{1,7}
2
或3
从1到7次
(?<=\\")
Precedeed by a double-quote (?<=\\")
前面加双引号
(?=\\")
Followed by a double-quote (?=\\")
后跟双引号
Snippet 片段
$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;
First, my suggested code. 首先,我建议的代码。 Then a review of the techniques employed on this page.
然后回顾此页面上使用的技术。
echo preg_replace_callback('/"([23]{1,7})"/',
function ($m) {
return str_replace(['2', '3'], ['d', 'e'], $m[1]);
},
$text
);
Stephane Janicaud's and BA_Webimax's preg_replace_callback()
answers have good components and not-so-good components in the execution, but the general logic is sound. Stephane Janicaud和BA_Webimax的
preg_replace_callback()
答案在执行过程中具有很好的组件,但不是很好,但是总的逻辑是合理的。 I'll take a moment to isolate some weakness/opportunities and offer some refinements. 我将花一些时间隔离一些弱点/机会并提供一些改进。
Stephane's pattern: /(?<=\\")[23]{1,7}(?=\\")/
misunderstands the question and leaves the double quotes in the input string. Stephane的模式:
/(?<=\\")[23]{1,7}(?=\\")/
误解了问题,并将双引号留在了输入字符串中。 He writes the most appropriate character class and quantifier expression (one to seven occurrences), but the lookarounds are an unnecessarily heavy burden on pattern efficiency; 他编写了最合适的字符类和量词表达式(一到七次出现),但是环顾四周给模式效率带来了不必要的沉重负担。 also, the backslash before the double quotes is needless.
同样,双引号前的反斜杠也是不必要的。 This pattern evaluates the OP's input string in a whopping 407 steps .
此模式以高达407个步骤的方式评估OP的输入字符串。
Next in line is an adaptation of BA_Webimax's pattern. 接下来的是BA_Webimax模式的改编。 His posted pattern does not offer the desired accuracy of only targeting
2
and 3
, but rather any non-double quote character. 他发布的模式并不能提供仅定位
2
和3
所需要的准确性,而是提供任何非双引号字符。 For this comparison, I'll use ~"([23]{1,7})"~
. 为了进行比较,我将使用
~"([23]{1,7})"~
。 This is a very tidy and effective pattern -- there are no lookarounds used, and the only drag is the capture group. 这是一种非常整洁而有效的模式-没有使用环顾四周,唯一的阻力是捕获组。 This pattern evaluates the string in a respectable 142 steps .
此模式以可观的142步评估字符串。
Because Stephane is passing one to seven characters to the anonymous function AND the switch
cases are ONLY checking for exact matches of 2
or 3
, his answer ends of mangling the string by eradicating the 3rd and 4th matches . 由于Stephane会将1到7个字符传递给匿名函数,并且
switch
情况仅检查2
或3
精确匹配,因此他的答案是通过消除第3和第4个匹配来破坏字符串。 This makes the answer simply wrong. 这使答案简直是错误的。 (The
Add other cases
comment is not a reasonable yatta yatta
for developers to code up -- and why should they?) (“
Add other cases
注释对于开发人员来说不是合理的“ yatta yatta
”,为什么要这么做?)
BA_Webimax performs a smart, direct, efficient action using str_replace()
on the first capture group string. BA_Webimax使用
str_replace()
对第一个捕获组字符串执行智能,直接,有效的操作。
I checked the performance speeds on 3v4l.org and str_replace()
edged out strtr()
on php7.2 using the input string. 我检查了3v4l.org上的性能速度,并使用输入字符串在php7.2上的
str_replace()
淘汰了strtr()
。 That said, executing a real benchmark would involve a larger volume of input data -- I just didn't go down that path. 也就是说,执行真实的基准测试会涉及大量输入数据-我只是没有走这条路。
Single-Function Replacements: 单功能替换:
str_replace(['2', '3'], ['d', 'e'], $m[1]);
strtr($m[1], ['2' => 'd', '3' => 'e']);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.