sab669
sab669

Reputation: 4104

Regex for the inclusion of one string and exclusion of a second string?

I'm looking for a regex to match these rules:

  1. Contains The contoller for path
  2. Contains a single quote ('), followed by any number of characters
  3. The characters must not end in .cs
  4. There must be a second single quote
  5. Contains was not found or does not implement IController

Sample Input:

Exception Message: The controller for path '/MyApplication/Scripts/jquery-1.10.2.min.js' was not found or does not implement IController.

Exception Message: The controller for path '/MyApplication/Content/bootstrap.min.css' was not found or does not implement IController.


I didn't work on our main application's error logging library / integration to our application, but I'm getting dozens of these log files telling me that my CSS and Javascript doesn't implement IController. Can't figure out why so I wrote something to just delete them in the mean time. It's a little bit more "rigid" than I'd like though:

string[] regexExpressions = {
             "(The controller for path)(\\s)'([^']*?)[.]js'(?:$|\\s)(was not found or does not implement IController.)",
             "(The controller for path)(\\s)'([^']*?)[.]css'(?:$|\\s)(was not found or does not implement IController.)"
          };

List<Regex> regexList = new List<Regex>();

foreach (string expression in regexExpressions)
    regexList.Add(new Regex(expression);

//Loop over each file in a directory
//Nested loop to iterate over my List<Regex>
//   to compare every file against every regex
//   building a list any time I find a match

//Delete files which match any one of my regex

(It's a little bit more sophisticated than that, but that's the important stuff)

I've just been going back and adding additional regular expressions to the string[] regexExpressions as I notice more and more types of unimportant error logs. However, I don't want to have to modify this tool every single time I find a new file type which throws an error I don't care about. Initially I wrote it for just *.js, then noticed *.css was throwing these too, and now today I found a few *.map files with this same error message....

So how can I change it to look for a single quote proceeded by anything but .cs?

I think I can probably get away with skipping the first two requirements in my list above, the important part is really just <not a .cs file>' was not found found or does not implement IController. I just included all the other stuff before that as I like to be as explicit as possible and avoid the risk of accidentally deleting something I might not mean to delete.

Upvotes: 0

Views: 974

Answers (2)

Niitaku
Niitaku

Reputation: 835

The following regex excludes the cs files:

'[^']+?\.(?!cs')[^'.]+?'

This expression checks if the text between the single quotes contains at least one character, a dot that is not followed by cs' but by at least one character. It also can still match lines where the extension starts with cs.

The regex group (?!something) is called a negative lookahead. You can read a bit more info here.

If you want to ensure the sentence, you can add it around like that:

The controller for path '[^']+\.(?!cs')[^'.]+?' was not found or does not implement IController\.

You can view it in action here or here.

Upvotes: 1

jdweng
jdweng

Reputation: 34429

This should work :

            string[] inputs = {
                "The controller for path '/MyApplication/Scripts/jquery-1.10.2.min.js' was not found or does not implement IController.",
                "The controller for path '/MyApplication/Content/bootstrap.min.css' was not found or does not implement IController."
            };

            string pattern = @"The controller for path '(?'path'.+)\.(?'ext'.+)'";

            foreach (string input in inputs)
            {
                
                Match match = Regex.Match(input, pattern);

                string ext = match.Groups["ext"].Value;

                if (match.Success && match.Groups["ext"].Value != "cs")
                {
                    Console.WriteLine(match.Groups["path"].Value + "." + match.Groups["ext"].Value);
                }
            }
            Console.ReadLine();

Upvotes: 0

Related Questions