24

How can I retrieve all lines of a document containing "strA", but not "strB", in the Visual Studio search box?

Alan Moore
  • 73,866
  • 12
  • 100
  • 156
Ricky
  • 34,377
  • 39
  • 91
  • 131

5 Answers5

45

For Visual Studio 2012 (and newer versions):

^(?!.*strB).*strA.*$

Explanation:

^           # Anchor the search at the start of the line
(?!.*strB)  # Make sure that strB isn't on the current line
.*strA.*    # Match the entire line if it contains strA
$           # Anchor the search to the end of the line

You might want to add (?:\r\n)? at the end of the regex if you also want to remove the carriage returns/line feeds along with the rest of the line.

Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
  • 6
    This worked. I had to extend to support multiple strings for exclusion, which worked out to be e.g. `^(?!.*strB)(?!.*strC)(?!.*strD).*strA.*$`. – DuckMaestro Nov 25 '15 at 02:59
18

For Visual Studio 2010 (and previous versions):

The Visual Studio search box has its own, bizarre version of regex syntax. This expression works as requested:

^~(.*strB).*strA

^ matches the beginning of a line. (Typically for a text editor, there's no "multiline" option; ^ and $ always match at line boundaries.)

. matches any character except a newline. (Not so typically, there appears to be no "single-line" or "dot-all" mode that lets dots match newlines.)

~(...) is the "prevent match" construct, equivalent (as far as I can tell) to the negative lookahead ((?!...)) used by the other responders.

Alan Moore
  • 73,866
  • 12
  • 100
  • 156
  • 5
    FYI, as of Visual Studio 2012 the dotNet regex engine is now used for searches, hence the bizarre syntax should now be gone. Nice answer but just be aware of which version of VS you are using. – redcalx Sep 18 '13 at 13:59
  • Testing in Visual Studio 2010 SP1Rel, this answer must be modified if "strB" might be AFTER "strA". Try `^~(.*strB).*strA~(.*strB)`. Or `~(strB).*strA.*~(strB)`. – ToolmakerSteve Sep 12 '17 at 18:37
1

You'd use Negative lookarounds but the expression is very complex if you don't know the expected position (or even order) of the terms. Do you know the order or pattern?

Otherwise I'd advise you to use another tool which could just as easily loop (or list comp) through a file line by line and do inStr or Contains or other simple, faster, logical tests...

annakata
  • 74,572
  • 17
  • 113
  • 180
1

I'm going to assume the search box actually accepts general regular expressions. Using negative lookahead:

(?!^.*strB.*$)strA

You'll need to set the multiline options (^and $ match at start/end of lines). If you can't set it using the dialog options, try:

(?m)(?!^.*strB.*$)strA

This is probably the default mode in that engine though.

wds
  • 31,873
  • 11
  • 59
  • 84
  • You need to anchor the whole regex, not just the lookahead. That means putting the `^` *outside* the lookahead and adding another `.*` in front of `strA`. But there's no need to anchor any part of the regex to the *end* of the line (i.e., the `.*$` can go). – Alan Moore Feb 06 '10 at 12:10
  • Well I don't know. As I look at it now I wrote it as "if a line does not contain strB, match strA". Still seems correct to me, since we're matching line by line. I think. Reading old regexes makes my brain hurt. – wds Feb 06 '10 at 12:36
0

This worked for me with Visual Studio 2010:

^.+[^(strB)].+(strA).+[^(strB)].+$

aleksandrm8
  • 320
  • 2
  • 5