2

A Questions for the regular expression/ sed experts out there: I need to beautify some c++ code. The code is littered with various version of the assignment operator with different types of spacing. i.e.

a=b
a =b
a= B
a  = b
a=  b
A = B. // the correct format needed, and so must be ignored by SED

There should only be one space around the =. If more are found, the extras must be removed.

I need to make a script that will scan through all files in folder and subfolders and search and replace as needed.

There are some variations, like the a+=b etc.

I run on OsX but have linux and windows machines available.

help much appreciated.

9
  • 1
    What's expected output for a+=b and a*=b etc? Commented Apr 6, 2017 at 17:30
  • 1
    You might be able to just run it through clang format Commented Apr 6, 2017 at 17:30
  • the expected answers for a+=b and a*=b would be a += b and a *= b Commented Apr 6, 2017 at 18:42
  • @nathan, tel me more about clang format... Commented Apr 6, 2017 at 18:43
  • @ jarod42:I have a simple text file with some tests: >> cat regtest.txt a=b asas asasa=bddfdf a =dfdf sasasa= ssdsd sdsd = sdsdsd RESULT: >> sed 's/([^ =])+ *([=+*/%-]?=)( )*([^ ])/$1 $2 $3/' regtest.txt a=b asas asasa=bddfdf a =dfdf sasasa= ssdsd sdsd = sdsdsd Commented Apr 6, 2017 at 18:46

2 Answers 2

1

You can use this sed to insert a single space before and after all = operators:

Input file:

cat file
a          ==b
a=b
a =b
a/=b
a *=b
a+= b
a-=   b
a= B
a%= B
a  = b
a=  b
A = B

sed command:

sed -E 's~[[:blank:]]*([-+*/%=]?=)[[:blank:]]*~ \1 ~g' file

a == b
a = b
a = b
a /= b
a *= b
a += b
a -= b
a = B
a %= B
a = b
a = b
A = B

This is regex used for matching (using ~ as delimiter):

  • ~[[:blank:]]*([-+*/%=]?=)[[:blank:]]*~ - matches 0 or more white spaces followed by an optional -+*/%= characters before a literal =. We are also capturing this operator in group #1

This is patter used in replacement:

  • ~ \1 ~ Which means a space before and after string captured in group #1
Sign up to request clarification or add additional context in comments.

7 Comments

I look at that regex and it looks like a swearword. ;>) I tested it with my simpler file and it works fine. You do not maybe feel like doing some education and explain the regex? Then maybe me and someone else can learn also from it. Anyway, thanks a lot for the answer.
I have added explanation in my answer.
I tried to also add the "!" and "<" to the exclusion list with no luck by changing it to: sed -E 's~[[:blank:]]*([-+*!</%=]?=)[[:blank:]]*~ \1 ~g' file Any idea why?
Try this: sed -E 's~[[:blank:]]*([-!<+*/%=]?=)[[:blank:]]*~ \1 ~g' file
You swapped the sequence inside the [ ]. Does not work, I end up with "! =" i.e. space in between ! and =. I also tried escaping the '!' with /, but also no luck.
|
0

It may interest you doing it with Perl

A simple file.cpp:

#include <iostream>

int main(){
    int i =          3;
    i     += 3;
    i-=3;
    i   *  =    3; // not valid just for sure
    i/=3;

    int i2
    =
    3;

    if( i
       =
       = i2 ){} // not valid just for sure
}

perl -lpe '$/=undef;s/\s*([=!%\*\/+-])?\s*(=)\s*/ $1$2 /g' file.cpp

the output:

#include <iostream>

int main(){
    int i = 3;
    i += 3;
    i -= 3;
    i *= 3;
    i /= 3;

    int i2 = 3;

    if( i == i2 ){}
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.