我遇到了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 -->
实际结果 (和以前一样),功能没有做任何事情
你对这个问题有任何想法吗?
答案 0 :(得分:1)
这里有三个主要问题:
内部函数htmlspecialchars()
和str_replace()
在 preg_replace()
逻辑适用之前评估。这意味着内部使用的$1
实际上是文字字符串“$ 1”而不是,如所执行的那样,是mathing正则表达式的内部部分。这意味着那里没有可以替换的。
对htmlspecialchars()
的内部调用会有效地将所有包含的“
”事件转换为“&lt; br /&gt;”,这将再次导致与{{{}的调用无法匹配1}},这就是必须交换两个函数调用的原因。
使用str_replace()
无法解决此问题,因为它的所有参数必须存在并在进入函数调用之前进行完全评估。这里的另一种选择是使用回调函数:这允许推迟那些函数调用,直到实际执行输出函数调用。
这对我有用:
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 );