Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

html

regex

php

I assume a regular expression might do the trick but I haven't been able to come up with one that works. I have some fairly long strings in PHP that I need to clean up. In some cases,   appears in stead of a single space character and in other caes     (etc) appears. I'd like to replace all of the single   occurence with a space but leave the others in place so that the intending can be maintained.

Any thoughts? I presume a regular expression could be used here but I've been struggling with making one for for a while!

like image 576
Programming123 Avatar asked Jul 19 '13 17:07

Programming123


2 Answers

You must use a negative lookbehind and a negative lookahead to ensure that you don't have other   around.

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

More informations about lookarounds here.

like image 128
Casimir et Hippolyte Avatar answered Sep 30 '22 15:09

Casimir et Hippolyte


Use an explicit regular expression that matches (not-&nbsp;)&nbsp;(not-&nbsp;) and add the replacement as $1 $2 (match 1 space match 2). You may have to code not-&nbsp; explicitly as ([^;]|[^p];|[^s]p;|[^b]sp;|[^n]bsp;|[^&]nbsp;).

Edit: While [negative] lookarounds may be useful (and certainly less total code), you may want to measure the speed of each approach. I have found that certain mechanisms in regular expressions can be painfully slow compared with others, although I cannot speak directly to the speed of lookarounds. If speed becomes an issue, you can skip the regular expressions and use a combination of strpos and substring operations and tests which are very often much faster than regular expressions, even if they are more cumbersome to create. I suggest this only because you have a very explicit string you are looking for; with less definite strings, regex is definitely the way to go.

For this instance (in pseudo-code), your string strpos search would be a simple as strpos($mystring, "&nbsp;") and once you have found a match, call strpos($mystring, "&nbsp;&nbsp;"). If the two index calls return the same value, you can skip this replacement and search the string after the indexed point (start your single &nbsp; search after indexDoubleFound + 12, but start your double &nbsp; search after indexDoubleFound + 6 to ensure that you don't miss any and you don't unintentionally replace).

like image 26
abiessu Avatar answered Sep 30 '22 16:09

abiessu