0

for code review and problem solving purposes, I'd need to be able to overlook all property getters in a large solution. I'm thinking "Regex and Powershell to the rescue".

I'd need a rexeg pattern that matches all getters in a C# file. For example, if this was the test string:

public string MockFullName
{
    get
    {
        string ns = FullName.Substring(0, FullName.Length - Name.Length - 1);
        return string.Format("{0}.Mock{1}", ns, Name);
    }
}

I'd need the match be:

get
{
    string ns = FullName.Substring(0, FullName.Length - Name.Length - 1);
    return string.Format("{0}.Mock{1}", ns, Name);
}

I've played around in https://regex101.com/ with pattern...

get(.|\n)*{(.|\n)*}

...which gives me too much back - includes the closing bracket from class too.

Typing this in PowerShell doesn't give anything back for the given C# file:

sls 'get(.|\n)*{(.|\n)*}' MyCSharpFileWithAProperty.cs

So, what kind of regex pattern would cater for this?

Thanks, pom

PS: For the record, I'm not interested in short form properties, and they can be skipped:

public string Name { get; set; }
Pompair
  • 7,083
  • 11
  • 60
  • 69
  • Where is your code? – Toto Nov 23 '16 at 10:40
  • Please show examples of the type of code that you *want* to match, and not just what you *don't want* to match. Also, if you've already tried creating a regex (and you *really* should try yourself before posting a question), post the code with that regex and state what doesn't work with it. – Lasse V. Karlsen Nov 23 '16 at 10:41
  • 3
    Having said that, be aware that using regex to match code syntax which involves braces (nested to an arbitrary depth) and comments and strings and whatnot is going to be arbitrary difficult, if not outright impossible. – Lasse V. Karlsen Nov 23 '16 at 10:42
  • 6
    What's about skipping RegEx and using Roslyn ? – Ralf Bönning Nov 23 '16 at 10:53
  • 1
    I agree with Lasse, It's going to be a pain to determine which of the potentially gazillions of brackets is the closing one. – Andrew Magerman Nov 23 '16 at 11:15
  • 3
    Looks like an X-Y problem. If you want to get all properties, use reflection, or Roslyn. Regex is clearly the wrong hammer here. – Mathieu Guindon Nov 23 '16 at 14:42
  • I'm thinking "Roslyn to the rescue". Definitely not a regular expression, C# is not a regular language. – Kris Vandermotten Nov 23 '16 at 15:32
  • 1
    @Mat'sMug: Reflection cannot distinguish auto-properties from those with an implementation, so Roslyn is needed. – Joey Nov 23 '16 at 15:35
  • You should use NDepend. It can even show added/removed properties based on a previous build. Even integrate it into your CI environment. Not everything needs to be custom built ;). – Myrtle Nov 23 '16 at 15:50
  • Any feedback on the 5 answers you received? – Thomas Ayoub Dec 03 '16 at 09:50
  • Hi Thomas, sorry it took so long, I was christmas-busy. Yeah, your answer works for me the best. Thanks for looking into it. Points for you. – Pompair Dec 04 '16 at 16:07

4 Answers4

1

Assuming that your file is correctly indented (ie: does not mix tabs & spaces), one solution is to use the following code:

Regex r = new Regex(@"get\s*?
                        ^(\s+){
                        [\s\S]*?
                        ^\1}", RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline);

var matches = r.Matches(input);
foreach(Match m in matches)
{
    Console.WriteLine(Regex.Replace(m.Value, "^" + m.Groups[1].Value, "", RegexOptions.Multiline));
}

Against:

public string MockFullName
{
    get
    {
        string ns = FullName.Substring(0, FullName.Length - Name.Length - 1);
        return string.Format("{0}.Mock{1}", ns, Name);
        if(true)
        {
            DoStuff();
        }
    }
}

public string MockFullName
{
    get
    {
        string ns = FullName.Substring(0, FullName.Length - Name.Length - 1);
        return string.Format("{0}.Mock{1}", ns, Name);
    }
}

It will output:

get
{
    string ns = FullName.Substring(0, FullName.Length - Name.Length - 1);
    return string.Format("{0}.Mock{1}", ns, Name);
    if(true)
    {
        DoStuff();
    }
}

get
{
    string ns = FullName.Substring(0, FullName.Length - Name.Length - 1);
    return string.Format("{0}.Mock{1}", ns, Name);
}
Thomas Ayoub
  • 29,063
  • 15
  • 95
  • 142
0

Try this:

Match match = Regex.Match(input, @"(get[\S\s]*})\s*}");
string asd = match.Groups[1].Value;

Maybe it needs some customization, but for a start it's fine I think.

UPDATE: the above code may fail for methods containing the word "get", so after a little modification this pattern should do the trick:

@"{\s*(get[\S\s]*})\s*}"
Mitulát báti
  • 2,086
  • 5
  • 23
  • 37
0

In c# this would work get \s*\{(?:[^{}]*|(?<open> \{ )|(?<-open> \}))+(?(open)(?!))\} which is a very slightly modified version of the first awnser to this Balance parentasis. If you are using a language that impiments prce regexes you could use get\s*({[^{}](?1)}).

The c# one works by going through all the test and adding any opening bracket it finds to open and if it finds a closing bracket it uses ?<-open> (.net balancing groups) to remove the last match of the group open. this puts back onto the macth befor that. If no matches are avalable it fails, this allow the regex to balance the brackets. At the end it uses (?(open)(?!)) to check there are nop remaining matches in open, if there are this fails. This effectivly means the the number of bracket have to match.

I hope this is what you want.

Community
  • 1
  • 1
milo.farrell
  • 662
  • 6
  • 19
0

Not a regular expression, also not custom reflection or Roslyn. Have you considered NDepend?

  • Its CQLinq syntax allows you to query for all getters in the project
  • You can integrate it into your existing CI setup: Define warning and error thresholds based upon CQlinq queries; you could see them als code quality guards. The errors can 'halt' CI for example.
  • Its there out of the box and offers lots of other review and inspection functionality. No need to invest in a custom solution.

Example image showing query results (note example queries for Methods not Properties).

example quering for methods

Myrtle
  • 5,761
  • 33
  • 47