Steven
Steven

Reputation: 2558

Why doesn't this regex work in grep?

I have a file with these contents:

void verifyFooBar() {
}

void verifyFooBar123() {
}

I am using grep to match function names which start with verify but don't contain numbers using this command: grep verify[a-zA-Z]+\( *

However I don't get any matches with grep. Why is this? I am able to see that this regex works using regex testers online. I am using OSX 10.9 if that matters.

Upvotes: 0

Views: 1545

Answers (2)

Ed Morton
Ed Morton

Reputation: 203899

+ is an ERE metacharacter. grep uses BREs by default. What you're trying to do written as a BRE would be:

$ grep 'verify[a-zA-Z][a-zA-Z]*(' file             
void verifyFooBar() {

and if you want to use EREs you need to tell grep that with -E but then escape the ( because that is also an ERE metacharacter but in this case you want it to be treated as a literal:

$ grep -E 'verify[a-zA-Z]+\(' file
void verifyFooBar() {

Some greps (and seds) have been enhanced in the past few years such that even when working on BREs you can "turn on" a given characters ERE metacharacter functionality by escaping it, e.g.:

$ grep 'verify[a-zA-Z]\+(' file 
void verifyFooBar() {

I think POSIX these days might even specify that you can use \<ERE meta-char> that way in BREs. The GNU tools do that, not sure which others. Some don't though, like the default tools on Solaris:

$ /bin/grep 'verify[a-zA-Z]\+(' file            
$ 

Upvotes: 3

vastlysuperiorman
vastlysuperiorman

Reputation: 1784

Single quote your regex string (to prevent your shell grabbing any bits of it), do escape the plus, and don't escape your open paren (so it can be interpreted as a literal character).

grep 'verify[a-zA-Z]\+(' *

This is tested and works

Upvotes: 3

Related Questions