0

I didn't see an exact duplicate of this regex question...

In Visual Studio 2012, I need to find all files with 'using' directives that match a specific name space.

Example:

  using System;
  using System.Collections;
  using System.Collections.Generic;
  using      System.Data;
  using System.Diagnostics;

I want to find all 'System' (substring A) namespace references EXCEPT those containing 'Collections' (substring B).

The desired results:

  using System;
  using      System.Data;
  using System.Diagnostics;

Seems like a good place to use a regex.

mobill
  • 589
  • 8
  • 14
  • Should a string like `using System.Generic.Collections;` pass or fail? – Jerry Feb 21 '14 at 20:22
  • Is order important? What about `using Aardvark.Collections.Management.System ;`. How about `using` statement with compound words like `using SystemManagementCorp.Collections`? – Nicholas Carey Feb 21 '14 at 20:37
  • Are you using VS find in files (using regex) util? –  Feb 21 '14 at 21:17
  • For my specific case I was looking for 'using' statements that always contain Substr A and never contain Substr B. Substr B happens to be our company namespace so it will be unique. Jerry and Nicholas-Carey, it should fail (I don't want to see those in the results). @sln, I did use VS find in files. – mobill Feb 21 '14 at 21:33

2 Answers2

0

This is the minimum regex that seems to work:

  ^.*System(?!\.Collections).*$

Breaking it into parts:

  ^                  # from the beginning of the string
  .*                 # match all leading ('using ' in my case)
  System             # match 'System'
  (?!\.Collections)  # don't match strings that contain '.Collections'
  .*$                #match all (.*) to the end of the line ($)

This variation:

  ^.*[ ]System(?!\.Collections).*$

will eliminate

  using my.System.Data;
  using mySystem.Diagnostics;

Related question #1

Related question #2

Rubular: A nice online regex utility

Caveat: I last played seriously with regex about 20 years ago so I'm a newbie again... hope I got the explanation right.

Community
  • 1
  • 1
mobill
  • 589
  • 8
  • 14
  • 1
    So, what did `using` have to do with it? Given the mode is (?-s), your regex matches `XXXXXXXXXXXXXXXXXXXXXX SystemYYYYYYYYYYYYYYYYYYYYY` Also, [ ] already satisfies the `\b`, so no need to include both (probably just [ ]). If `'using System.something'` are the results you get, then thats all you have. Hey, its a temporary search, no need to be specific anyway. –  Feb 21 '14 at 21:26
  • 1
    It can basically be rewritten as `[ ]System(?!\.Collections)` since full lines display in the output anyway. –  Feb 21 '14 at 21:38
  • `using` - in the end, nothing. Yes on the `\b` or `[]` point, only one is needed. And yes, `[ ]System(?!\.Collections)` works, but because of the substrings returns a bunch of matches that aren't what I'm looking for (although, useful for other reasons). – mobill Feb 21 '14 at 21:46
  • Your original regex had `.*` before and after. So, there is absolutely no difference by clipping them out, you get the same results. –  Feb 21 '14 at 22:48
0

You need to learn about

  • (?!...). zero-width negative lookahead.
  • (?<!...). zero-width negative lookbehind

The regular expression

Regex rxFooNotBar = new Regex( @"(?<!bar)Foo(?!Bar)" ) ;

will match strings containing "Foo" but not "Bar".

For your specific case — find using statements that reference System namespaces that don't have 'Collections' as a child namespace, this should do the trick:

Regex rxUsingStatements = new Regex( @"^\s*using\s+System\.(?!Collections)[^; \t]*\s*;" ) ;

should do you.

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135