Tags: #silversearcher #ag #ack #grep #PCRE #regex #vim #lookahead #ripgrep
As noted in this thread: https://github.com/ggreer/the_silver_searcher/issues/459#issuecomment-118785490
The trick to get the PCRE engine have .
to include new lines is to prefix your pattern with ‘Perl options’ (http://www.pcre.org/original/doc/html/pcrepattern.html#SEC13).
So to get PCRE_DOTALL
we need to prefix our regex pattern with (?s)
.
For example, consider a file test.txt
with the following content:
Line 1
Line 2
Line 3
We can match all three lines using:
ag '(?s)Line 1.+Line 3' test.txt
NOTE: The above only works on a file, not when data is piped into
ag
.
If you want to check for lines not preceded by another line, e.g. you’re looking for…
name:
anyOf:
- ...
While avoiding:
name:
type: object
anyOf:
- ...
Then use a negative lookbehind assertion:
rg --context 2 --pcre2 --regexp '(?<!type: object)anyOf:'
Imagine you have the following code across multiple files:
serviceID, serviceVersion, err := cmd.ServiceDetails(cmd.ServiceDetailsOpts{
AllowActiveLocked: true,
Client: c.Globals.Client,
Manifest: c.manifest,
Out: out,
ServiceVersionFlag: c.serviceVersion,
VerboseMode: c.Globals.Flag.Verbose,
})
You want to find every instance of the function call cmd.ServiceDetails
but ignore any that have a ServiceNameFlag
field set (which isn’t set in the above example).
To achieve this you’d use a negative lookahead (?!<pattern>)
. The following example uses the Vim ack plugin to search for the function call, then lookahead to make sure we don’t find the field, and then keep matching until the end of the function call…
:Ack! '(?s)cmd\.ServiceDetails\((?!.+?ServiceNameFlag).+?}\)'