0

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 '15 at 20:43
  • @Cyrus Sample input is already there....But I added what the desired output should look like – Andy May 15 '15 at 20:45
  • Sorry, my mistake. – Cyrus May 15 '15 at 20:48
3

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 '15 at 21:04
  • I agree Otheus, perl would be more elegant in that case – CaptainCap May 15 '15 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. – G-Man May 15 '15 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 '15 at 21:25
  • @G-Man Andy's cat...that made me laugh – Andy May 15 '15 at 21:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.