【问题标题】:PHP: String Wrap from ArrayPHP:数组中的字符串换行
【发布时间】:2021-07-03 05:40:35
【问题描述】:

使用下面我可以匹配数组中的所有项目,但我只能替换预期的匹配值。有没有办法做同样的事情,但不是直接替换,而是用指定的值包装匹配的文本?

当前代码:

$colours = array("Red", "Blue", "Green");
$string = "There are three Red and Green walls.";

echo str_replace($colours, "?", $string);

当前输出

There are three ? and ? walls.

想要的输出

There are three %1%Red%2% and %1%Green%2% walls.

【问题讨论】:

  • 如果你想要一个原始的解决方案 - 然后为替换提供一个数组,每个单词都包含在 %1%…%2% 中。
  • 你的意思是preg_replace("/\b(?:" . implode('|', $colours) . ")\b/", '%1%$0%2%', $string)3v4l.org/9077N

标签: php arrays string


【解决方案1】:

根据您是否要考虑上下文,解决方案会有所不同。

如果您打算在任何上下文中按原样匹配字符串并用%1%%2% 随附的副本替换,则需要使用

preg_replace("/" . implode("|", array_map(function($i) {return preg_quote($i, "/");}, $colours)) . "/", '%1%$0%2%', $string)

这里使用| OR 运算符形成正则表达式,$colours 数组中的项目中的所有特殊字符都使用\ 使用preg_quote 函数进行转义。替换中的$0 指的是整个匹配值。

如果$colours 是带有空格的短语,您需要对项目进行排序,以便较长的字符串在前:

rsort($colours, SORT_FLAG_CASE | SORT_STRING);
echo "\n" . preg_replace("/" . implode("|", array_map(function($i) {return preg_quote($i, "/");}, $colours)) . "/", '%1%$0%2%',$string);

如果这些$colours是简单的英文字母单词,并且你想将它们作为整个单词匹配,你不需要preg_quote,你可以使用单词边界,比如:

preg_replace("/\b(?:" . implode('|', $colours) . ")\b/", '%1%$0%2%', $string)

要使搜索不区分大小写,请在 preg_replace 第一个参数的最后一个 / 正则表达式分隔符之后添加 i 标志。

PHP demo

$colours = array("Red", "Blue", "Green");
$string = "There are three Red and Green walls.";

echo preg_replace("/" . implode("|", array_map(function($i) {return preg_quote($i, "/");}, $colours)) . "/", '%1%$0%2%', $string);
// => There are three %1%Red%2% and %1%Green%2% walls.

echo "\n" . preg_replace("/\b(?:" . implode('|', $colours) . ")\b/", '%1%$0%2%', $string);
// => There are three %1%Red%2% and %1%Green%2% walls.

$colours = array("Red", "Blue", "Green", "Blue jeans");
$string = "There are three Red and Green walls and Blue jeans.";
rsort($colours, SORT_FLAG_CASE | SORT_STRING);

echo "\n" . preg_replace("/" . implode("|", array_map(function($i) {return preg_quote($i, "/");}, $colours)) . "/", '%1%$0%2%',$string);
// => There are three %1%Red%2% and %1%Green%2% walls and %1%Blue jeans%2%.

【讨论】:

  • 是否可以在不影响包装字符串的情况下进行不区分大小写的检查?
  • 我用过这个,好像可以,有意义吗"/\b(?i:" . implode('|', $colours) . ")\b/"
  • @llanato 如果您只需要不区分大小写地查找术语,并包装找到的匹配项,只需添加 i 标志,"/\b(?:" . implode('|', $colours) . ")\b/i"
【解决方案2】:

最简单但不是最有效的:

$colours = array("Red", "Blue", "Green");
$colours_replacment = array('%1%Red%2%', '%1%Blue%2%', '%1%Green%2%');
$string = "There are three Red and Green walls.";

echo str_replace($colours, $colours_replacment, $string);

简单有效:

$colours = array("Red", "Blue", "Green");
$string = "There are three Red and Green walls.";

foreach($colours as $colour) {
    $string = str_replace($colour, '%1%' . $colour . '%2%', $string);
}

echo $string;

【讨论】:

    【解决方案3】:

    你想要的是preg_replace。您将能够用包含匹配项的字符串替换匹配项。在这种情况下,"%1%$0%2%" $0 将被替换为匹配项。

    但是,您需要引用(使用preg_quote)并向数组成员添加分隔符。我们可以通过array_map 做到这一点。

    这是代码:

    echo preg_replace
    (
        array_map
        (
            function($input)
            {
                return "/".preg_quote($input, "/")."/";
            },
            $colours
        ),
        "%1%$0%2%",
        $string
    );
    

    不,我不建议假设它们在不引用的情况下可以安全使用,即使在这种情况下它们是安全的。是的,用它们创建一个单一的正则表达式模式是可行的,但为什么要麻烦呢?

    【讨论】:

      【解决方案4】:

      我认为您可以使用 array_map。这是我的例子:

      $colours = array("红色", "蓝色", "绿色");

      $string = "红绿三面墙。";

      $func = function($value) 使用 ($colours){

      return in_array($value, $colours) ? "%1%". $value ."%2%" : $value;
      

      };

      $text = array_map($func, explode(" ", $string));

      $text = implode(" ", $text);

      回显$文本; `

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-21
        • 1970-01-01
        • 1970-01-01
        • 2011-06-26
        • 2017-10-13
        • 2017-05-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多