2016-11-23 191 views
0

代码审查和解决问题的目的,我需要能够忽略大型解决方案中的所有属性获得者。我在想“RegexPowershell来营救”。正则表达式匹配C#属性获取器

我需要一个rexeg模式匹配C#文件中的所有getter。 例如,如果这是测试字符串:

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

我需要的比赛是:

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

我在https://regex101.com/与模式玩耍了......

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

......这给了我太多的回报 - 也包括了班级的括号。

键入这个PowerShell不会放弃任何东西对于给定的C#文件:

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

因此,将满足什么样的正则表达式的这个?

感谢, POM

PS:为了记录在案,我以短形式特性不感兴趣,他们可以跳过:

public string Name { get; set; } 
+0

你的代码在哪里? – Toto

+0

请显示您希望匹配的代码类型的示例,而不仅仅是您不希望匹配的代码。另外,如果你已经尝试创建一个正则表达式(你真的*应该在发布问题之前尝试自己),请使用该正则表达式发布代码,并指出哪些代码不适用。 –

+3

话虽如此,请注意使用正则表达式来匹配涉及大括号(嵌套到任意深度)的代码语法以及注释和字符串,以及不会完全不可能的任意困难。 –

回答

1

假设你的文件正确缩进(即:不混合标签&空格),一个解决方案是使用下面的代码:

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)); 
} 

反对:

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); 
    } 
} 

这将输出:

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); 
} 
0

试试这个:

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

也许它需要一些定制,但一开始我觉得很好。

UPDATE: 上面的代码可能无法包含单词“get”方法,所以稍加修改后,这个模式应该做的伎俩:

@"{\s*(get[\S\s]*})\s*}" 
+0

\ s includes \ r&n –

+0

Checked and you right!我修改了我的答案。 –

+0

不错。现在试着反对我的意见;) –

0

在C#这样的工作得到\s*\{(?:[^{}]*|(?<open> \{)|(?<-open> \}))+(?(open)(?!))\}这是一个非常略加修改第一awnser的这个Balance parentasis。如果您使用的语言是impémentsprc​​e regexes,您可以使用get \ s *({[^ {}] (?1)})。

c#的工作原理是通过所有的测试,并添加它打开的任何开头括号,如果它发现它使用的右括号? < -open>(。净平衡组)删除打开组的最后一场比赛。这就回到了这种情况。如果没有匹配可用,则失败,这允许正则表达式来平衡括号。最后它使用(?(open)(?!))来检查是否存在打开的nop剩余匹配项,如果失败。这有效地意味着支架的数量必须匹配。

我希望这是你想要的。

0

不是正则表达式,也不是自定义反射或Roslyn。你考虑过NDepend吗?

  • 其CQLinq语法允许在项目
  • 你可以把它集成到现有的CI设置查询所有干将:定义基于CQlinq查询警告和错误阈值;你可以看到他们的代码质量卫士。例如,这些错误可能会“中止”CI。
  • 它提供了很多其他的检查和检查功能。无需投资定制解决方案。

显示查询结果的示例图像(注意“方法不属性”的示例查询)。

example quering for methods