Search code examples
regexfindstr

How to write a search pattern to include a space in findstr?


I want to search all files in a certain directory for occurrences of statements such as

  Load frmXYZ

I am on Windows 7, using the findstr command. I tried:

  findstr /n Load.*frm *.*

But this gives me unwanted results such as:

 If ABCFormLoaded Then Unload frmPQR

So I tried to put a blankspace between Load and frm and gave the command like this:

 findstr /n Load frm *.*

But this simply searched for all occurrences of the word load or all occurrences of the word frm. How do I get around this problem?


Solution

  • If you use spaces, you need the /C: option to pass the the literal string(s) to the regex /R option.
    Once the it gets to the regex, it's treated as a regex.

    That said, this is typical MS trash.

    Use two regex search strings

    The bottom line is that you have to use 2 strings to handle cases where
    Load frm is at the beginning like so:

    • Load frm apples bananas carrots

    OR in the middle like so:

    • some other text Load frm and more.

    Version without character classes

    Below is using XP sp3, windows 7 may be different, both are trash!

    findstr /N /R /C:" *Load *frm" /C:"^Load *frm" test.txt

    7:Load frm is ok    
    8:    Load     frm is ok  
    

    Mind the Colon

    NOTE: The colon in /C: is MANDATORY for this to work.

    If you leave out the colon then findstr's error handling is just to treat /C as an invalid option, ignore that invalid option and go ahead anyway. Leading to unexpected and unwanted output.

    Equivalent version using character classes

    findstr /N /R /C:"[ ][ ]*Load[ ][ ]*frm" /C:"^Load[ ][ ]*frm" test.txt

    Character classes breakdown

    // The first regex search string breaks down like this:
    [ ]   // require 1 space
    [ ]*  // optional many spaces
    Load  // literal 'Load'
    [ ]   // require 1 space
    [ ]*  // optional many spaces
    frm   // literal 'frm'
    
    // The second regex search string breaks down like this:
    ^     // beginning of line
    Load  // literal 'Load'
    [ ]   // require 1 space
    [ ]*  // optional many spaces
    frm   // literal 'frm'
    

    A real regex might be \bLoad\s+frm