如何替换single&;nbsp';s有一个空格,但如果有多个&;nbsp;s


How can I replace single  's with a space but, not if there are multiple  s?

我认为正则表达式可能会起作用,但我还没能想出一个有效的表达式。我在PHP中有一些相当长的字符串需要清理。在某些情况下,出现 而不是单个空格字符,在其他情况下出现   (等)。我想用一个空格替换所有出现的单个 ,但保留其他的空格,以便保持意图。

有什么想法吗?我想这里可以使用正则表达式,但我已经为创建一个正则表达式而苦苦挣扎了一段时间!

必须使用负向后看和负向前看,以确保周围没有其他 

$str = preg_replace('~(?<!&nbsp;)&nbsp;(?!&nbsp;)~i', ' ', $str);

有关环视的更多信息,请点击此处。

使用与(not-&nbsp;)&nbsp;(not-&nbsp;)匹配的显式正则表达式,并将替换项添加为$1 $2(匹配1空格匹配2)。您可能需要将not-&nbsp;明确地编码为([^;]|[^p];|[^s]p;|[^b]sp;|[^n]bsp;|[^&]nbsp;)

编辑:虽然[负面]环视可能很有用(当然总代码也更少),但您可能需要衡量每种方法的速度。我发现,与其他机制相比,正则表达式中的某些机制可能慢得令人痛苦,尽管我不能直接谈论查找的速度。如果速度成为一个问题,您可以跳过正则表达式,使用strpossubstring操作和测试的组合,这些操作和测试通常比正则表达式快得多,即使创建起来更麻烦。我建议这样做只是因为你有一个非常明确的字符串,你正在寻找;对于不太明确的字符串,regex无疑是最好的选择。

对于这个例子(在伪代码中),字符串strpos搜索将像strpos($mystring, "&nbsp;")一样简单,一旦找到匹配项,就调用strpos($mystring, "&nbsp;&nbsp;")。如果两个index调用返回相同的值,则可以跳过此替换并搜索索引点之后的字符串(在indexDoubleFound + 12之后开始单&nbsp;搜索,但在indexDoubleFound + 6之后开始双&nbsp;搜索,以确保不会遗漏任何内容,也不会无意中替换)。