简体   繁体   English

如何用特定字母替换特定数字(在长度限制内)?

[英]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次的双引号之间找到23

(?<=\\")[23]{1,7}(?=\\")

"233223322" won't be replaced with "deeddeedd" because it has more than 7 characters (9) “ 233223322”不会替换为“ deededed”,因为它具有7个以上的字符(9)

Demo 演示版

Explanation 说明

[23]{1,7} Either 2 or 3 from 1 to 7 times [23]{1,7} 23从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;

Online demo 在线演示

First, my suggested code. 首先,我建议的代码。 Then a review of the techniques employed on this page. 然后回顾此页面上使用的技术。

Code: ( Demo ) 代码:( 演示

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. 我将花一些时间隔离一些弱点/机会并提供一些改进。

Regarding the pattern: 关于模式:

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. 他发布的模式并不能提供仅定位23所需要的准确性,而是提供任何非双引号字符。 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步评估字符串。

Regarding the character replacement: 关于字符替换:

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情况仅检查23精确匹配,因此他的答案是通过消除第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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM