I'm finally learning regexps and training with ack. I believe this uses Perl regexp.
I want to match all lines where the first non-blank characters are if (<word> !
, with any number of spaces in between the elements.
This is what I came up with:
^[ \t]*if *\(\w+ *!
It only nearly worked. ^[ \t]*
is wrong, since it matches one or none [space or tab].
What I want is to match anything that may contain only space or tab (or nothing).
For example these should not match:
// if (asdf != 0)
else if (asdf != 1)
How can I modify my regexp for that?
EDIT adding command line
ack -i --group -a '^\s*if *\(\w+ *!' c:/work/proj/proj
Note the single quotes, I'm not so sure about them anymore.
My search base is a larger code base. It does include matching expressions (quite some), but even for example:
274: }else if (y != 0)
, which I get as a result of the above command.
EDIT adding the result of mobrule's test
Mobrule, thanks for providing me a text to test on. I'll copy here what I get on my prompt:
C:\Temp\regex>more ack.test
# ack.test
if (asdf != 0) # no spaces - ok
if (asdf != 0) # single space - ok
if (asdf != 0) # single tab - ok
if (asdf != 0) # multiple space - ok
if (asdf != 0) # multiple tab - ok
if (asdf != 0) # spaces + tab ok
if (asdf != 0) # tab + space ok
if (asdf != 0) # space + tab + space ok
// if (asdf != 0) # not ok
} else if (asdf != 0) # not ok
C:\Temp\regex>ack '^[ \t]*if *\(\w+ *!' ack.test
C:\Temp\regex>"C:\Program\git\bin\perl.exe" C:\bat\ack.pl '[ \t]*if *\(\w+ *!' a
ck.test
if (asdf != 0) # no spaces - ok
if (asdf != 0) # single space - ok
if (asdf != 0) # single tab - ok
if (asdf != 0) # multiple space - ok
if (asdf != 0) # multiple tab - ok
if (asdf != 0) # spaces + tab ok
if (asdf != 0) # tab + space ok
if (asdf != 0) # space + tab + space ok
// if (asdf != 0) # not ok
} else if (asdf != 0) # not ok
The problem is in my call to my ack.bat!
ack.bat contains:
"C:\Program\git\bin\perl.exe" C:\bat\ack.pl %*
Although I call with a caret, it gets away at the call of the bat file!
Escaping the caret with ^^
does not work.
Quoting the regex with " "
instead of ' '
works. My problem was a DOS/win problem, sorry for bothering you all for that.
^\s*if\s*\(\S+\s*!
\S
for non-white-space. \w
will not match any special chars, so if ($word
will not match. May be that's OK with your specs, in which case \w
(alphanumeric plus "_"
) is OK$ perl5.8 -e '{$s="else if (asdf \!= 1)"; if ($s =~ /^\s*if\s*\((\S+)\s*\!/) { print "|$1|\n";} else { print "NO MATCH\n";}}' NO MATCH $ perl5.8 -e '{$s="// if (asdf \!= 0)"; if ($s =~ /^\s*if\s*\((\S+)\s*\!/) { print "|$1|\n";} else { print "NO MATCH\n";}}' NO MATCH $ perl5.8 -e '{$s=" if (asdf \!= 0)"; if ($s =~ /^\s*if\s*\((\S+)\s*\!/) { print "|$1|\n";} else { print "NO MATCH\n";}}' |asdf| $ perl5.8 -e '{$s="if (asdf \!= 0)"; if ($s =~ /^\s*if\s*\((\S+)\s*\!/) { print "|$1|\n";} else { print "NO MATCH\n";}}' |asdf| $ perl5.8 -e '{$s="if (\$asdf \!= 0)"; if ($s =~ /^\s*if\s*\((\S+)\s*\!/) { print "|$1|\n";} else { print "NO MATCH\n";}}' |$asdf|
In both ack
and grep
, *
matches zero or more, not zero or one. So I think you already have the right solution. What test cases aren't giving you the results you want?
# ack.test
if (asdf != 0) # no spaces - ok
if (asdf != 0) # single space - ok
if (asdf != 0) # single tab - ok
if (asdf != 0) # multiple space - ok
if (asdf != 0) # multiple tab - ok
if (asdf != 0) # spaces + tab ok
if (asdf != 0) # tab + space ok
if (asdf != 0) # space + tab + space ok
// if (asdf != 0) # not ok
} else if (asdf != 0) # not ok
Results:
$ ack '^[ \t]*if *\(\w+ *!' ack.test
if (asdf != 0) # no spaces - ok
if (asdf != 0) # single space - ok
if (asdf != 0) # single tab - ok
if (asdf != 0) # multiple space - ok
if (asdf != 0) # multiple tab - ok
if (asdf != 0) # spaces + tab ok
if (asdf != 0) # tab + space ok
if (asdf != 0) # space + tab + space ok
$ ack -v '^[ \t]*if *\(\w+ *!' ack.test
// if (asdf != 0) # not ok
} else if (asdf != 0) # not ok
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With