【问题标题】:PHP preg_replace: ignore matches in replaced valuesPHP preg_replace:忽略替换值中的匹配项
【发布时间】:2013-10-28 08:19:12
【问题描述】:

我想使用 preg_replace 将主题中的标记替换为值。 主题中的标记是问号或命名参数。 (想想 PDO 风格)

我当前的方法工作正常,直到其中一个值本身包含问号。 (或命名变量。)在这种情况下,整个系统都会出错:替换值中的问号本身会被下一个值替换。

基本上,我不想替换 $values 数组中的任何内容。所以我想停止 preg_replace 的“递归”性质。

最好的方法是什么?

孤立的例子:

<?php

// Values that will be replaced
$values = array (1, 2, 'bla bla ? bla', 'NULL', 4, 'woop woop', 'waap waap');

// Keys used for replacing
$keys = array ('/[?]/', '/[?]/', '/[?]/', '/[?]/', '/[?]/', '/:testvar1/', '/:testvar2/');

// Original text
$original = ":testvar1, ?, ?, ?, ?, ?, :testvar2";

// Actual replaced text
$actual = preg_replace ($keys, $values, $original, 1);

// Expected replaced text
$expected = "woop woop, 1, 2, bla bla ? bla, NULL, 4, waap waap";

echo '<pre>';
echo "Actual:\n";
echo $actual . "\n\n";
echo "Expected:\n";
echo $expected . "\n\n";
echo "Result:\n";

if ($actual == $expected)
{
    echo '<span style="color: green;">Success!</span>';
}
else
{
    echo '<span style="color: red;">Failure!</span>';   
}

有什么建议吗? :-) 谢谢!

【问题讨论】:

    标签: php preg-replace


    【解决方案1】:

    这可以通过前瞻断言来解决,如下所示:

    // Keys used for replacing
    $keys = array ('/\?(?=,)/', '/\?(?=,)/', '/\?(?=,)/', '/\?(?=,)/', '/\?(?=,)/');
    

    这将使 RE 引擎匹配任何后跟逗号的问号,没有使逗号成为匹配的一部分。但是,如果您曾经有包含问号后跟逗号的替换值,您将再次遇到这种情况。

    【讨论】:

    • 这并不能解决问题,只是将其推回。如果替换包含?,怎么办?
    • “但是,如果您曾经有包含问号后跟逗号的替换值,您将再次遇到这种情况。”
    • 所以您已经意识到了这个问题......您将如何尝试解决它?
    【解决方案2】:

    使用preg_replace_callback,以便您可以手动分配替换,如下所示:

    $values = [1,2,'bla bla ? bla','NULL',4];
    $original = "?, ?, ?, ?, ?";
    $actual = preg_replace_callback("/[?]/",function($m) use (&$values) {
        return array_shift($values);
    });
    

    完成!

    【讨论】:

    • 你是对的,这解决了最初的问题。但是,密钥必须每次都相同。问题中可能不是很明显,但 $keys 数组也可以不同。将编辑原始问题,很抱歉造成混淆:)
    • 我已经完成了这个场景。我也尝试过使用 preg_replace_callback,但是使用不同的顺序它完全疯了:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    • 1970-01-01
    相关资源
    最近更新 更多