Php 如何用&;替换HTML PRE元素中的所有空格;nbsp;

Php 如何用&;替换HTML PRE元素中的所有空格;nbsp;,php,regex,Php,Regex,近似 除了我只想修改前置标记之间的空格。例如: <table atrr="zxzx"><tr> <td>adfa a adfadfaf></td><td><br /> dfa dfa</td> </tr></table> <pre class="abc" id="abc">abc abc</pre> <pre>123 123</pre&

近似

除了我只想修改前置标记之间的空格。例如:

<table atrr="zxzx"><tr>
<td>adfa a   adfadfaf></td><td><br /> dfa  dfa</td>
</tr></table>
<pre class="abc" id="abc">abc abc</pre>
<pre>123 123</pre>
do
     $html = preg_replace('/(<pre.*>.*) (.*<\/pre>)/', '$1&nbsp;$2', $html, 1, $count);
while($count);

echo $html;

adfa a adfadfaf>
dfa dfa 美国广播公司 123 123
将转换为(注意,pre标记可能包含属性,也可能不包含属性):


adfa a adfadfaf>
dfa dfa 美国广播公司 123 123
do
$html=preg_replace(“/(.*)(.*)/”、“$1$2”、$html、1$count);
而(计算),;
echo$html;
我不确定是否有更好的解决办法。我不太熟悉所有的preg函数。

do
$html=preg_replace(“/(.*)(.*)/”、“$1$2”、$html、1$count);
而(计算),;
echo$html;
我不确定是否有更好的解决办法。我不太熟悉所有的preg函数。

$html=preg\u replace(
“#(\]*>)(.*)()#Umie”
,“$1”。str_替换(”,“$2”),“$3”
,$html);
已经过测试,可与您提供的示例字符串一起使用。这是一个不灵活的选项,您不想替换
之间的空格。如果
部分跨越多行,也可以使用

注意:如果您有嵌套的情况,如
,则此操作将失败。如果您希望能够解析它,则需要使用

更新: 我做了一些基准测试,结果表明回调版本每100000次迭代大约快1秒,所以我想我也应该提到这个选项

$html=preg\u replace\u回调(
“#(\]*>)(.*)()#Uim”
,函数($matches){
返回$matches[1]。str_replace(“”,,$matches[2])。$matches[3];
}
,$html);
这需要PHP 5.3或更高版本,早期版本不支持匿名函数。

$html=preg\u replace(
“#(\]*>)(.*)()#Umie”
,“$1”。str_替换(”,“$2”),“$3”
,$html);
已经过测试,可与您提供的示例字符串一起使用。这是一个不灵活的选项,您不想替换
之间的空格。如果
部分跨越多行,也可以使用

注意:如果您有嵌套的情况,如
,则此操作将失败。如果您希望能够解析它,则需要使用

更新: 我做了一些基准测试,结果表明回调版本每100000次迭代大约快1秒,所以我想我也应该提到这个选项

$html=preg\u replace\u回调(
“#(\]*>)(.*)()#Uim”
,函数($matches){
返回$matches[1]。str_replace(“”,,$matches[2])。$matches[3];
}
,$html);

这需要PHP 5.3或更高版本,早期版本不支持匿名函数。

Dupe?欺骗
内部的
*
是贪婪的。如果您有2个
标记,它将消耗太多。@请注意,在这种情况下,贪婪并没有什么错,因为我将它放在一个循环中,它仍然可以正常工作。这并不像Arjan的人力资源管理那样是一个很好的解决方案……现在我真的很困惑。我以为第一次迭代会取代最后一个空间。。。为什么它不这么做?(它仍然比它需要的循环次数多了一次……而且它根本不需要循环)啊。。。没有关系。忘记了“点匹配所有”修饰符…这就是让我困惑的地方!这正是我所期待的。您将看到它还转换跨度之间的空间。这就是为什么贪婪是坏的!
内部的
*
是贪婪的。如果您有2个
标记,它将消耗太多。@请注意,在这种情况下,贪婪并没有什么错,因为我将它放在一个循环中,它仍然可以正常工作。这并不像Arjan的人力资源管理那样是一个很好的解决方案……现在我真的很困惑。我以为第一次迭代会取代最后一个空间。。。为什么它不这么做?(它仍然比它需要的循环次数多了一次……而且它根本不需要循环)啊。。。没有关系。忘记了“点匹配所有”修饰符…这就是让我困惑的地方!这正是我所期待的。您将看到它还转换跨度之间的空间。这就是为什么贪婪是坏的!您可以在替换字符串中放入函数??文档中哪里有这样的说法?那是因为正则表达式的
e
修饰符。这意味着将对结果字符串进行求值,因此只要确保它生成正确的PHP代码,就可以包含函数调用。另一种解决方案是使用
preg\u replace\u callback
并指定一个回调函数。您需要添加
's'
单行/点匹配所有修饰符,以使点星号跨越多行。您可以在替换字符串中放入一个函数??文档中哪里有这样的说法?那是因为正则表达式的
e
修饰符。这意味着将对结果字符串进行求值,因此只要确保它生成正确的PHP代码,就可以包含函数调用。另一种解决方案是使用
preg\u replace\u callback
并指定一个回调函数。您需要添加
's'
单行/点匹配所有修饰符,以使点星成为跨行。
do
     $html = preg_replace('/(<pre.*>.*) (.*<\/pre>)/', '$1&nbsp;$2', $html, 1, $count);
while($count);

echo $html;
$html = preg_replace(
      '#(\<pre[^>]*>)(.*)(</pre>)#Umie'
    , "'$1'.str_replace(' ', '&nbsp;', '$2').'$3'"
    , $html);
$html = preg_replace_callback(
      '#(\<pre[^>]*>)(.*)(</pre>)#Uim'
    , function($matches){
          return $matches[1].str_replace(' ', '&nbsp;', $matches[2]).$matches[3];
      }
    , $html);