2

This question already has an answer here:

I've created a regex which I need to run with grep, I'm pretty sure the regex is fine as it works with online regex tools, however when I run

grep -r -P -o -h '(?<=(?<!def )my_method )(["'])(?:(?=(\\?))\2.)*?\1'

I get the error Syntax error: ")" unexpected.

marked as duplicate by don_crissti, Eric Renouf, Satō Katsura, GAD3R, roaima Apr 3 '17 at 16:41

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

10

Your regular expression is quoted with single quotes, but it also contains a single quote.

The single quote in ["'] needs to be escaped, or it will signal the end of the quoted string to the shell.

This will fix it:

grep -r -P -o -h '(?<=(?<!def )my_method )(["'\''])(?:(?=(\\?))\2.)*?\1'
#                                            ^^^^

With ["'\''], the first ' ends the first part of the string, the \' inserts a literal single quote, and the last ' starts a new single quoted string that will be concatenated with the previous bits. Only the middle single quote will end up in the regular expression itself, the other two will be removed by the shell.

  • 3
    Nice Tricky method. Alternative : (["\x27]) will work fine (replacing the single quote with it's ascii code) – George Vasiliou Apr 3 '17 at 12:23
  • @GeorgeVasiliou That's also a good solution, yes. \x27 is as many characters as '\''. – Kusalananda Apr 3 '17 at 12:24
  • 1
    Though '\'' is transferable to other non-regex situations whereas \x27 is not. – Muzer Apr 3 '17 at 14:41
5

As @Kusalananda explained, the problem is the ' inside the regex. A simple solution is to use " for the regex since " can be escaped even inside a "-quoted string, unlike ' which cannot be escaped inside a '-quoted string:

grep -rPoh "(?<=(?<!def )my_method )([\"'])(?:(?=(\\?))\2.)*?\1"

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