Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

regex match any whitespace

Tags:

regex

php

I want to make a replacement using regex and preg_replace function. this is my code

$verif = "/wordA(\s*)wordB(?! wordc)/i";
$replacement = 'wordA wordb wordc';
$newvar = preg_replace($verif, $replacement, $article->text);

That works if only we have one whitespace between wordA and wordB. I need to match what ever the number of whitespaces between wordA & wordB.

example:

wordA (10 or more whitespace) wordB -> wordA wordb wordc same wordA(1 whitespace) wordB -> wordA wordb wordc ...

like image 269
user3344311 Avatar asked Feb 23 '14 20:02

user3344311


People also ask

What is the regex for whitespace?

\s stands for “whitespace character”. Again, which characters this actually includes, depends on the regex flavor. In all flavors discussed in this tutorial, it includes [ \t\r\n\f]. That is: \s matches a space, a tab, a carriage return, a line feed, or a form feed.

What is used to match any whitespace?

\s matches any whitespace character [ \r\n\t\f ] . \S matches any non-white space character. Here, denotes whitespace characters, and denotes non-white space characters.

Does \w include spaces?

\W means "non-word characters", the inverse of \w , so it will match spaces as well.

What is the regex for space in Java?

Therefore, the regular expression \s matches a single whitespace character, while \s+ will match one or more whitespace characters.


2 Answers

Your regex should work 'as-is'. Assuming that it is doing what you want it to.

wordA(\s*)wordB(?! wordc) 

This means match wordA followed by 0 or more spaces followed by wordB, but do not match if followed by wordc. Note the single space between ?! and wordc which means that wordA wordB wordc will not match, but wordA wordB wordc will.

Here are some example matches and the associated replacement output:

enter image description here

Note that all matches are replaced no matter how many spaces. There are a couple of other points: -

  • (?! wordc) is a negative lookahead, so you wont match lines wordA wordB wordc which is assume is intended (and is why the last line is not matched). Currently you are relying on the space after ?! to match the whitespace. You may want to be more precise and use (?!\swordc). If you want to match against more than one space before wordc you can use (?!\s*wordc) for 0 or more spaces or (?!\s*+wordc) for 1 or more spaces depending on what your intention is. Of course, if you do want to match lines with wordc after wordB then you shouldn't use a negative lookahead.

  • * will match 0 or more spaces so it will match wordAwordB. You may want to consider + if you want at least one space.

  • (\s*) - the brackets indicate a capturing group. Are you capturing the whitespace to a group for a reason? If not you could just remove the brackets, i.e. just use \s.

Update based on comment

Hello the problem is not the expression but the HTML out put   that are not considered as whitespace. it's a Joomla website.

Preserving your original regex you can use:

wordA((?:\s| )*)wordB(?!(?:\s| )wordc) 

The only difference is that not the regex matches whitespace OR  . I replaced wordc with \swordc since that is more explicit. Note as I have already pointed out that the negative lookahead ?! will not match when wordB is followed by a single whitespace and wordc. If you want to match multiple whitespaces then see my comments above. I also preserved the capture group around the whitespace, if you don't want this then remove the brackets as already described above.

Example matches:

enter image description here

like image 183
acarlon Avatar answered Sep 21 '22 13:09

acarlon


The reason I used a + instead of a '*' is because a plus is defined as one or more of the preceding element, where an asterisk is zero or more. In this case we want a delimiter that's a little more concrete, so "one or more" spaces.

word[Aa]\s+word[Bb]\s+word[Cc] 

will match:

wordA wordB     wordC worda wordb wordc wordA   wordb   wordC 

The words, in this expression, will have to be specific, and also in order (a, b, then c)

like image 35
mrres1 Avatar answered Sep 20 '22 13:09

mrres1