str_replace 在我的密码箱上不起作用

str_replace is not working on my codebox

我遇到了 str_replace()

的问题

输入值

 <br />
<!-- BEGIN switch_user_authreply --><br />
<div id="mobileActionBar"><br />
    <a href="{U_POST_REPLY_TOPIC}" rel="nofollow" class="navbar"><br />
        <div class="mobileActionLabel">{L_POST_REPLY_TOPIC}</div><br />
    </a><br />
</div><br />
<!-- END switch_user_authreply -->

使用的函数

 $message = preg_replace('~\[code\](.*?)\[/code\]~s', '<textarea as="codebox">'.str_replace("<br />","\n", htmlspecialchars("")).'</'.'textarea>', $message);

预期结果(其中
=> \n)

<!-- BEGIN switch_user_authreply -->
<div id="mobileActionBar">
    <a href="{U_POST_REPLY_TOPIC}" rel="nofollow" class="navbar">
        <div class="mobileActionLabel">{L_POST_REPLY_TOPIC}</div>
    </a>
</div>
<!-- END switch_user_authreply -->

真实结果 (和之前一样),函数什么都没做

你对这个问题有什么想法吗?

这里主要有3个问题:

  1. 内部函数 htmlspecialchars()str_replace() 在 应用 preg_replace() 逻辑之前 求值。这意味着内部使用的 </code> 实际上是文字字符串“$1”,而不是预期的数学正则表达式的内部部分。也就是说<em>里面没有<br />可以替换</em>.</p></li> <li><p>对 <code>htmlspecialchars() 的内部调用会有效地将所有包含的“
    ”事件转换为“
    ”,这将再次导致调用不匹配到 str_replace(),这就是必须交换两个函数调用的原因。

  2. preg_replace() 无法解决这个问题,因为它的所有参数都必须存在并在被送入函数调用之前进行全面评估。这里的替代方法是使用回调函数:这允许将那些函数调用推迟到输出函数调用的实际执行。

这对我有用:

<?php

$input = <<< EOT
some arbitrary outer text
[code]
<br />
<!-- BEGIN switch_user_authreply --><br />
<div id="mobileActionBar"><br />
    <a href="{U_POST_REPLY_TOPIC}" rel="nofollow" class="navbar"><br />
        <div class="mobileActionLabel">{L_POST_REPLY_TOPIC}</div><br />
    </a><br />
</div><br />
<!-- END switch_user_authreply -->
[/code]
some arbitrary outer text
EOT;

$output = preg_replace_callback(
    '~\[code\](.*)\[/code\]~s',
    function ($m) {
        return 
            '<textarea as="codebox">'
            .htmlentities(str_replace('<br />',"\n", $m[1]))
            .'</textarea>';
    },
    $input
);

print_r($output);

输出为:

some arbitrary outer text
<textarea as="codebox">


&lt;!-- BEGIN switch_user_authreply --&gt;

&lt;div id=&quot;mobileActionBar&quot;&gt;

    &lt;a href=&quot;{U_POST_REPLY_TOPIC}&quot; rel=&quot;nofollow&quot; class=&quot;navbar&quot;&gt;

        &lt;div class=&quot;mobileActionLabel&quot;&gt;{L_POST_REPLY_TOPIC}&lt;/div&gt;

    &lt;/a&gt;

&lt;/div&gt;

&lt;!-- END switch_user_authreply --&gt;
</textarea>
some arbitrary outer text

哇,你一下子就把很多东西结合起来了。

请记住,preg_replace 只会转换字符串值中的“$1”以供替换。

你所做的实际上是这样的:

htmlspecialchars("") // equals 
str_replace("<br />", "\n", ""); // which matches nothing

我认为我的方法是使用 preg_match 而不是替换:

<?php

$message = <<<EO_MESSAGE
[code]
 <br />
<!-- BEGIN switch_user_authreply --><br />
<div id="mobileActionBar"><br />
    <a href="{U_POST_REPLY_TOPIC}" rel="nofollow" class="navbar"><br />
        <div class="mobileActionLabel">{L_POST_REPLY_TOPIC}</div><br />
    </a><br />
</div><br />
<!-- END switch_user_authreply -->
[/code]
EO_MESSAGE;


if ( preg_match( '~\[code\](.*?)\[/code\]~s', $message, $matches) ) {

    $found = $matches[1];

    $found = str_replace( '<br />', "\n", $found);
    $found = '<textarea as="code">' . $found . '</textarea>';

    $message = str_replace( $matches[0], $found, $message );
}

print_r( $message );

如果您想替换多个 [代码] 块,请改用 preg_match_all 功能:

<?php

$message = <<<EO_MESSAGE
[code]
 <br />
<!-- BEGIN switch_user_authreply --><br />
<div id="mobileActionBar"><br />
    <a href="{U_POST_REPLY_TOPIC}" rel="nofollow" class="navbar"><br />
        <div class="mobileActionLabel">{L_POST_REPLY_TOPIC}</div><br />
    </a><br />
</div><br />
<!-- END switch_user_authreply -->
[/code]
EO_MESSAGE;


if ( preg_match_all( '~\[code\](.*?)\[/code\]~s', $message, $matches, PREG_SET_ORDER) ) {

    foreach ($matches as $match ) {
        print_r($match);
        $found = $match[1];

        $found = str_replace('<br />', "\n", $found);
        $found = '<textarea as="code">'.$found.'</textarea>';

        $message = str_replace($match[0], $found, $message);
    }
}

print_r( $message );