【问题标题】:Find all if else and else if statements with no parentheses查找所有不带括号的 if else 和 else if 语句
【发布时间】:2016-04-01 16:47:16
【问题描述】:

我在 c# 中有一堆代码,其中有一些行,其中不带括号的 if 或 else 语句有一些额外的行,这些行会导致错误的行为。我正在寻找一个正则表达式来查找所有可能出现此问题的地方,以便我可以手动查找它。

澄清我的意思。在代码中有几个地方(我直到现在才发现)以下代码是错误的。

if (notInitialized)
    Initialize();
    AdditionalInitializationNotUseThisWhenAlreadyInitialized();

应该是

if (notInitialized) {
    Initialize();
    AdditionalInitializationNotUseThisWhenAlreadyInitialized();
}

我试过这个if\s*\(.*\)([\n\r\s[^{]]*.*);*,但它不仅给了我想要的结果。它也有if (notInitialized) { 部分。我几乎没有使用正则表达式的经验。

如何在不检查代码中的每个 if/else/else if 的情况下找到所有这些情况,只检查没有大括号的情况?

【问题讨论】:

标签: c# regex


【解决方案1】:

您面临的一个问题是正则表达式在.* 上尽可能多地匹配以找到模式匹配。因此,根据所使用的选项(例如,. 匹配除 \n 之外的任何内容或任何内容),您将得到不满意的结果。

另一个问题是您需要递归匹配,例如跳过与表达式中嵌套的 '(' 一样多的)。只有极少数的正则表达式引擎可以做到这一点;幸运的是,.NET 可以通过“平衡组”,但它是正则表达式的棘手且高度高级的应用。此外,对于要正常工作,您还必须识别字符串和字符文字(用引号括起来),以免在其中计算括号。

编辑这个 .NET 的正则表达式应该非常可靠地找到这些 if 和 else 语句:

\b(if\s*\(((?:[^()"']|'(\\.|[^'\\])'|"(\\.|[^"\\])"|(?<parens>\()|(?<-parens>\)))*(?(parens)(?!))\))|else)\s*[^{\s]

虽然这显示了正则表达式的强大功能,但它非常神秘,正确的方法是使用真正的解析器(例如 Roslyn)。

【讨论】:

  • 别误会我的意思,你非常了解正则表达式(可能比我好)。但我不明白为什么这么简单的事情需要这么大的正则表达式。
  • @MarioDekena 因为它涵盖了极端情况:它应该处理字符串或字符文字中的花括号和非花括号之类的任何内容,甚至是谓词中的 lambda 表达式,例如 if (x.Any(y =&gt; { return z(); })) 等。
  • 这就像我需要的一样。它看起来像伏都教(就像任何正则表达式一样;))但我深入研究它以了解它是如何完成的。谢谢。
  • 感谢布瑟!请注意,如果要允许 } else if (x) { 构造,可以将模式中的 else 替换为 else(?!\s+if\b) 以跳过这些。我也想知道为什么我的帖子被否决了......
  • 我看到了一些极端情况,它有时会发现一些 { 或遗漏了应该匹配的 if 语句。但它做了我想要的。
【解决方案2】:

你可以用这个:

if \(.+?\)[^{]*?\n[^{]*?[^{]

如果你没有这种格式的 ifs

if (notInitialized) 
{
    Initialize();
    AdditionalInitializationNotUseThisWhenAlreadyInitialized();
}

这也有效:

if \(.+?\)[^{]*?\n

它会检测,如果带有“if”的行最后没有 {。它也有点短。

【讨论】:

  • @Lucero 您的示例有效。这一个班轮最后没有{。它也可以使用“{”作为字符串。甚至对于两行版本。
  • @Lucero 也有效...阅读我的正则表达式!它最后有一个换行符。在此之前,它确保在最后一个 ) 之后没有 {。
  • 大多数文件都被格式化为在新行中以 { 开头。一些年长的已经排好队了。
  • @Booser 是的,我知道这一点。大多数人都有他们想要的ifs的偏好。因此,IDE 被配置为以这种方式格式化它们。由于在他的示例中他使用了内联格式,因此可以合理地假设他的 IDE 可能会像这样格式化它们。
  • 我希望你能明白……正则表达式不能在所有情况下都可靠地工作。 if (DoesItFail) a="{"; 将被视为“有效”,即使它不是,if (DoesItFail) { b(); }; 即使它是有效的,也会被视为无效。
猜你喜欢
  • 2014-11-11
  • 2012-07-02
  • 2017-06-14
  • 1970-01-01
  • 1970-01-01
  • 2019-04-09
  • 1970-01-01
相关资源
最近更新 更多