str_replace无法在我的代码框上运行

时间:2015-11-22 12:05:08

标签: php preg-replace str-replace

我遇到了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("$1")).'</'.'textarea>', $message);

预期结果(其中
=&gt; \ 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 -->

实际结果 (和以前一样),功能没有做任何事情

你对这个问题有任何想法吗?

2 个答案:

答案 0 :(得分:1)

这里有三个主要问题:

  1. 内部函数htmlspecialchars()str_replace()preg_replace()逻辑适用之前评估。这意味着内部使用的$1实际上是文字字符串“$ 1”而不是,如所执行的那样,是mathing正则表达式的内部部分。这意味着那里没有可以替换的

  2. htmlspecialchars()的内部调用会有效地将所有包含的“
    ”事件转换为“&lt; br /&gt;”,这将再次导致与{{{}的调用无法匹配1}},这就是必须交换两个函数调用的原因。

  3. 使用str_replace()无法解决此问题,因为它的所有参数必须存在并在进入函数调用之前进行完全评估。这里的另一种选择是使用回调函数:这允许推迟那些函数调用,直到实际执行输出函数调用。

  4. 这对我有用:

    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);
    

答案 1 :(得分:0)

哇,你要一次性结合很多东西。

请注意,preg_replace只会在提示替换的字符串值中转换“$ 1”。

你正在做的事实是:

htmlspecialchars("$1") // equals $1
str_replace("<br />", "\n", "$1"); // 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 );

如果您想要替换多个[code]块,请使用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 );