Regex help ... to strip blanks only in certain combinations

Viewed 43

I am not a regex specialist unfortunately. So, I searched here and used some regex I found. That "half solves" my requirements already, now I search for the small missing piece.

In general, I am working on lines of code with PHP's built in tokenizer. At the end, I get a code string containing Whitespace, Tabs, and breaks. What I found here already cleaned this "unnecessary whitespace". But I would like to go a bit further:

$foo [ 'bar' ], $foo ['bar' ], $foo [ 'bar'] (containing some blanks)

should all go to: $foo['bar'] (no blanks anymore)

$foo [ "bar" ], $foo ["bar" ], $foo [ "bar"]

should go to: $foo ["bar"]

BUT: $foo [ 'this is different' ] shall go to $foo['tis is different'] (retaining the significant blanks)

At the moment I use:

$_S = array( " [", " '", "' ", " ]" );
$_R = array( "[", "'", "'", "]" );
$_tx = preg_replace( '/\s+/', ' ', $A_tx);
$_tx = str_replace( $_S, $_R, $_tx );

But for sure, the work can also be done with only one, more sophisticated regex?

1 Answers

If you want to use a single pattern, one option could be making use of 2 capture groups and an alternation with a branch reset group.

I assume that $foo['tis is different'] should be $foo['this is different']

In the replacement use the 2 groups $1$2

\$\w+\K(?|\h*(\[)\h*('[^']+')\h*|(\h*\[)\h*("[^"]+")\h*)(?=])

The pattern matches

  • \$\w+ Match $ and 1+ word chars
  • \K Forget what is matched so far
  • (?| Branch reset group
    • \h*(\[)\h*('[^']+')\h* Capture [ in group 1 and the opening till closing ' in group 2, and match all the surrounding spaces to be removed
    • | Or
    • (\h*\[)\h*("[^"]+")\h* Capture the spaces and [ in group 1 and the opening till closing " in group 2 and match the spaces around the " only
  • ) Close branch reset group
  • (?=]) Assert a ] char directly to the right

Regex demo | Php demo

$re = '/\$\w+\K(?|\h*(\[)\h*(\'[^\']+\')\h*|(\h*\[)\h*("[^"]+")\h*)(?=])/m';
$str = '$foo [ "bar" ], $foo ["bar" ], $foo [ "bar"]
$foo [ \'bar\' ], $foo [\'bar\' ], $foo [ \'bar\']
$foo [ \'this is different\' ]';

$result = preg_replace($re, '$1$2', $str);

echo $result;

Output

$foo ["bar"], $foo ["bar"], $foo ["bar"]
$foo['bar'], $foo['bar'], $foo['bar']
$foo['this is different']
Related