regexripgrep

Regex if then without else in ripgrep


I am trying to match some methods in a bunch of python scripts if certain conditions are met. First thing i am looking at is if import re exists in a file, and if it does, then find all cases of re.sub(something). I tried following the documentation here on how to use if then without else regexs, but cant seem to make it work with ripgrep with or without pcre2.

My next approach was to use groups, so rg -n "(^import.+re)|(re\.sub.+)" -r '$2', but the issue with this approach is that because the first import group matches, i get a lot of empty files back in my output. The $2 is being handled correctly.

I am hoping to avoid doing a or group capture, and use the regex if option if possible.

To summarize, what I am hoping for is, if import re appears anywhere in a file, then search for re\.sub.+ and output only the matching files and lines using ripgrep. Using ripgrep is a hard dependency.

Some sample code:

import re

for i in range(10):
    re.match(something)
    print(i)

re.sub(something)

Solution

  • This can be accomplished pretty easily with a shell pipeline and xargs. The idea is to use the first regex as a filter for which files to search in, and the second regex to show the places where re.sub occurs.

    Here are three Python files to test with.

    import-without-sub.py has an import re but no re.sub:

    import re
    
    for i in range(10):
        re.match(something)
        print(i)
    

    import-with-sub.py has both an import re and an re.sub:

    import re
    
    for i in range(10):
        re.match(something)
        print(i)
    
    re.sub(something)
    

    And finally, no-import.py has no import re but does have a re.sub:

    for i in range(10):
        re.match(something)
        print(i)
    
    re.sub(something)
    

    And now here's the command to show only matches of re.sub in files that contain import re:

    rg '^import\s+re$' --files-with-matches --null | xargs -0 rg -F 're.sub('
    

    --files-with-matches and --null print out all matching file paths separated by a NUL byte. xargs -0 then reads those file paths and turns them into arguments to be given to rg -F 're.sub('. (We use --null and -0 in order to correctly handle file names that contain spaces.)

    Its output in a directory with all three of the above files is:

    import-with-sub.py
    7:re.sub(something)