I am learning the secret of regexp. I'm tired, so I may miss something obvious - but I see no reason for this.
In the examples below, I use perl - but I saw it for the first time in VIM, so I assume this is due to more than one regexp engine.
Suppose we have this file:
$ cat data 1 =2 3 =4 5 =6 7 =8
Then we can remove the spaces before the '=' character with ...
$ cat data | perl -ne 's,(.)\s+=(.),\1=\2,g; print;' 1=2 3=4 5=6 7=8
Note that in each row, all instances of the match are replaced; we used the / g search modifier, which does not stop at the first replacement, and instead goes to the replacement until the end of the line.
For example, both the space before '= 2' and the space before '= 4' were deleted; on the same line.
Why not use simpler constructs like 's, =, =, g'? Well, we were preparing for more complex scenarios ... where the right side of the assignments are quoted strings and can be either single or double quotes:
$ cat data2 1 ="2" 3 ='4 =' 5 ='6' 7 ="8"
To do the same job (remove the space before the equal sign), we must be careful, because the lines can contain an equal sign - therefore, we mark the first quote that we see and look for it through the backlinks:
$ cat data2 | perl -ne 's,(.)\s+=(.)([^\2]*)\2,\1=\2\3\2,g; print;' 1="2" 3='4 =' 5='6' 7="8"
We used the \ 2 backlink to search for something that is not the same quote as the one we first saw, as many times as you like ([^ \ 2] *). Then we searched for the most original quote (\ 2). If found, we used backlinks to refer to the relevant parts in the target replacement.
Now look at this:
$ cat data3 posAndWidth ="40:5 =" height ="1" posAndWidth ="-1:8 ='" textAlignment ="Right"
What we want here is to remove the last space character that exists before all instances of '=' in each line. As before, we cannot use the simple 's, = ", =", g', because the lines themselves may contain an equal sign.
So, we follow the same pattern as above and use backlinks:
$ cat data3 | perl -ne "s,(\w+)(\s*) =(['\"])([^\3]*)\3,\1\2=\3\4\3,g; print;" posAndWidth="40:5 =" height ="1" posAndWidth="-1:8 ='" textAlignment ="Right"
It works ... but only in the first match of the line! The space following "textAlignment" was not deleted, and none of them were on top of it ("height").
Basically, it seems that / g no longer works: running the same replace command without / g produces exactly the same result:
$ cat data3 | perl -ne "s,(\w+)(\s*) =(['\"])([^\3]*)\3,\1\2=\3\4\3,; print;" posAndWidth="40:5 =" height ="1" posAndWidth="-1:8 ='" textAlignment ="Right"
It appears that / g is ignored in this regular expression. Any ideas why?