58

This answer suggests that grep -P supports the (?:pattern) syntax, but it doesn't seem to work for me (the group is still captured and displayed as part of the match). Am I missing something?

I am trying grep -oP "(?:syntaxHighlighterConfig\.)[a-zA-Z]+Color" SyntaxHighlighter.js on this code, and expect the results to be:

wikilinkColor
externalLinkColor
parameterColor
...

but instead I get:

syntaxHighlighterConfig.wikilinkColor
syntaxHighlighterConfig.externalLinkColor
syntaxHighlighterConfig.parameterColor
...
waldyrious
  • 3,683
  • 4
  • 33
  • 41

1 Answers1

86

"Non-capturing" doesn't mean that the group isn't part of the match; it means that the group's value isn't saved for use in back-references. What you are looking for is a look-behind zero-width assertion:

grep -Po "(?<=syntaxHighlighterConfig\.)[a-zA-Z]+Color" file
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Kent
  • 189,393
  • 32
  • 233
  • 301
  • Note that all lookbehinds are zero width – barlop Apr 11 '16 at 10:47
  • 9
    Lookbehinds need to be fixed length. In this case it helps, but it doesn't in others. – Cromax Jul 17 '16 at 20:12
  • 29
    For references, `(?<=…)` is **positive lookbehind assertion**, `(?<!…)` is **negative lookbehind assertion**, `(?=…)` is **positive lookahead assertion**, and `(?!…)` is **negative lookahead assertion**. [More here](http://www.regular-expressions.info/lookaround.html). – Rockallite Feb 08 '17 at 07:11
  • congrats on gold grep! – fedorqui May 08 '17 at 14:09
  • 7
    Is there any variant of this that would handle variable width? E.g. if instead of the dot, I had an unknown number of spaces at the end of the lookbehind and wanted to do `grep -Po "(?<=syntaxHighlighterConfig +)[a-zA-Z]+Color" file`. Right now I get the complaint `grep: lookbehind assertion is not fixed length`. Thanks. – SSilk May 30 '17 at 18:01
  • @SSilk You'll probably want to use `vim` or Python or something if you want to be able to do it all with a regex. If you're just looking to get rid of some spaces after you've captured the main thing, you should be able to remove them in a loop after running `grep`. – Seldom 'Where's Monica' Needy Jul 14 '17 at 04:47
  • Your lookbehind assertion cannot be variable length. Your lookbehind assertion is this part: "(?<=syntaxHighlighterConfig +)". Putting the plus there says "one or more of the preceding character", i.e. the space. You just can't have a lookbehind assertion that could turn out to be more than one length. Maybe grep for just one space there, and then pass the result through 'tr' or 'sed' to remove the spaces. – Todd Walton Feb 05 '19 at 14:52
  • 2
    You could use `\K` as a variable length negative lookbehind... `Keep the stuff left of \K.` – Ray Foss Sep 11 '20 at 03:07