代码之家  ›  专栏  ›  技术社区  ›  Welton v3.62

正则性头痛

  •  6
  • Welton v3.62  · 技术社区  · 15 年前

    我想验证一个脚本引擎的C源代码。我只想确保System.Math 可以引用类成员。我正在尝试创建一个正则表达式,它将匹配一个点,后跟一个大写字母,后跟任意数量的单词字符,以一个不带前缀的单词边界结束System.Math.

    (?<!Math)\.[A-Z]+[\w]*
    

    适用于:

    return Math.Max(466.89/83.449 * 5.5);  // won’t flag this
    return Xath.Max(466.89/83.449 * 5.5);  // will flag this
    

    如果前面没有Math,则它与.Max正确匹配。然而,现在我正试图扩展正则表达式以包含System,我无法让它工作。

    我尝试了正则表达式的这些排列以及更多:

    ((?<!System\.Math)\.[A-Z]+[\w]*)
    ((?<!(?<!System)\.Math)\.[A-Z]+[\w]*)
    ((?<!System)\.(?<!Math)\.[A-Z]+[\w]*)
    ((?<!System)|(?<!Math)\.[A-Z]+[\w]*)
    ((?<!System\.Math)|(?<!Math)\.[A-Z]+[\w]*)
    

    使用以下语句:

    return System.Math.Max(466.89/83.449 * 5.5);
    return System.Xath.Max(466.89/83.449 * 5.5);
    return Xystem.Math.Max(466.89/83.449 * 5.5);
    

    我尝试了所有我能想到的方法,但是它要么总是匹配第二个元素(.Math或.Xath),要么什么都不匹配。

    如果有人怜悯我,指出我做错了什么,我会非常感激的。

    提前谢谢, 韦尔顿

    2 回复  |  直到 15 年前
        1
  •  2
  •   Alan Moore Chris Ballance    15 年前

    诀窍是确保你永远不会在任何地方开始匹配一个成员的名字,但在开始。那么就简单地用一个前瞻来找出你所看到的东西是否从 System.Math. . 试试这个正则表达式:

    (?<![\w.])(?!(?:System\.)?Math\.)(?:[A-Z]\w*\.)+[A-Z]\w*\b
    

    \w )或限定成员名称的中间( . Math. System.Math. )再试一次。要么全是,要么什么都不是。

    然而,这 比赛 Math.Max 如果前面没有 System. . 你真的需要它吗,或者这只是为全名开发正则表达式的中间步骤?

    编辑:我先走了 系统。 零件可选。

        2
  •  2
  •   dawg    15 年前

    如果您只是在寻找示例中所述的内容,那么这个正则表达式就可以做到这一点。

    ^[\w\s]*?[A-Z]\w+\.[A-Z]\w+\.(?<!System\.Math\.)

    它匹配所有调用,而不是系统.Math.XXX只要:a)有两个 .

    return System.Math.Max(466.89/83.449 * 5.5); // no match
    return System.Xath.Max(466.89/83.449 * 5.5); // match
    return Xystem.Math.Max(466.89/83.449 * 5.5); // match
    System.Math.Max(466.89/83.449 * 5.5);  // no match
    System.Xath.Max(466.89/83.449 * 5.5);  // match
    Xystem.Math.Max(466.89/83.449 * 5.5);  // match
    return System.Math.Max(466.89/83.449 * 5.5); // no match
    return System.Xath.Max(466.89/83.449 * 5.5); // match
    return Xystem.Math.Max(466.89/83.449 * 5.5); // match
    Math.Max(466.89/83.449 * 5.5);               // no match - only one '.'
    System.Max.Math(466.89/83.449 * 5.5);        // match
    

    不过,我同意这些评论;任何regex都是非常脆弱的,只应该被认为是文本编辑器类型的帮助。如果你希望它是防弹的,你需要一个解析器。

    推荐文章