I use the following command to remove surrounding spaces between array keys that are strings or integers in PHP files:

sed -ri "s/\[ ([0-9]+|(\x27|\x22).*(\x27|\x22)) \]/[\1]/g" file.php

I thought I had covered all bases but it's failing when there are multiple array brackets on the same line, So this:

if ( $myarray[ 'id' ] == 7 && $myarray[ 'status' ] == true )

Becomes this:

if ( $myarray['id' ] == 7 && $myarray[ 'status'] == true )

When it should look like this:

if ( $myarray['id'] == 7 && $myarray['status'] == true )

It's removing the space on the right for the first set of brackets and the space on the left for the second set.

How can I modify the command so it will replace the spaces between all array brackets on each line for the whole file?

  • Show sample input and your desired output for that sample input.
    – Cyrus
    May 15, 2015 at 20:43
  • @Cyrus Sample input is already there....But I added what the desired output should look like
    – Andy
    May 15, 2015 at 20:45
  • Sorry, my mistake.
    – Cyrus
    May 15, 2015 at 20:48

1 Answer 1


Your problem comes from the .*. If you only match every character that is not a ' or a " it will work: sed -ri "s/\[ ([0-9]+|(\x27|\x22)[^\x27\x22]*(\x27|\x22)) \]/[\1]/g" file.php

Even better (to take possible " or ' into account):

sed -ri "s/\[ ([0-9]+|(\x27|\x22)[^\2]*(\2)) \]/[\1]/g" file.php
  • 1
    To the OP: In this case, perl -i -pe might be more useful, since perl RE's will distinguish between "greedy" and "non-greedy" globs. You want "non-greedy" in this case. The syntax would be nearly the same: perl -i -pe 's/\[\s+(\x27.*?\x27)\s+\]/[$1]/g' Or something like that.
    – Otheus
    May 15, 2015 at 21:04
  • I agree Otheus, perl would be more elegant in that case
    – CaptainCap
    May 15, 2015 at 21:12
  • 1
    I agree that non-greedy regular expressions are more elegant than the @Captain’s answer.  But that second answer (with the \2s) handles $myarray[ "Andy's cat" ] correctly, which ['"].*?['"] will not. May 15, 2015 at 21:19
  • You can do the same thing in perl: perl -i -pe 's/\[\s+((\x27|\x22).*?$2)\s+\]/[$1]/g'
    – CaptainCap
    May 15, 2015 at 21:25
  • @G-Man Andy's cat...that made me laugh
    – Andy
    May 15, 2015 at 21:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .