Search code examples
phpregexperlspam-prevention

Inverse of Perl regex X modifier


I would like to use a Perl regular expression to match strings like this:

spaM
s p a m
sp Am
S   p a   m

Looking at Perl's x modifier, I should be able to do this:

<?php
echo preg_match('#spam#ix', 's p a   m');
?>

But this prints out 0 (false). The x modifier actually ignores whitespace on the regex, not the string being analyzed. How would I do it the other way around? That is, ignore whitespace on the string being analyzed rather than my regex? I'm aware there are multi-step ways to do this, such as first stripping all white space from the string, but I wanted to know if there was a powerful one-step regex solution.


Solution

  • The #x modifier works the other way around. It allows to use extraneous whitespace in the regex, which is ignored for searching:

    preg_match('# s p a m #ix')
    

    Will only ever match "spam".

    What you need to do in order to find arbitrary whitespace with your regex is to inject \s* between any letters:

    preg_match('# S \s* P \s* A \s* M #ix', 's p a   m');
    

    You can automate/simplify that a bit, by converting words into an appropriate regex with intermixed \s* using:

    $regex = join('\s*', str_split("spam", 1));
    preg_match("#$regex#ix", "s p a m");