代码之家  ›  专栏  ›  技术社区  ›  Greg B

忽略正则表达式匹配的空白

  •  8
  • Greg B  · 技术社区  · 14 年前

    我需要匹配8个或更多的数字,其序列可以包括空格。

    例如,以下所有匹配项都是有效的。

    12345678
    1 2345678
    12 3 45678
    1234 5678
    12 34567 8
    1 2 3 4 5 6 7 8
    

    目前我有 \d{8,} 但这只会捕获8个或更多数字的实心块。
    [\d\s]{8,} 不会工作,因为我不希望空白有助于计数字符捕获。

    3 回复  |  直到 14 年前
        1
  •  8
  •   Suamere    7 年前

    稍后再说,但这真的需要一个正确的答案,以及一个原因。谁知道这个问题会有这么复杂的答案,对吧?哈哈。但是在regex中有很多关于间距的考虑。

    首先;不要在正则表达式中加空格。这样做会使你的正则表达式不可读,也不可维护。回忆起用鼠标突出显示一个空间,以确保它只有一个空间浮现在脑海中。这将破坏regex:,但不会破坏:[],因为字符类中的重复被忽略。如果你需要精确的空格数,你可以在这样的字符类中看到: [ ]{3} . 与没有character类的意外相比:{3}<--这实际上是在找5个空间,喔!

    第二;保持自由空间 (?x) 选项,这使您的正则表达式可注释和自由空间。你不应该担心使用这个选项的人可能会破坏你的正则表达式,因为你决定在其中放置随机的键盘空格。也, (?x) 在字符类中忽略键盘空间,如下所示: [ ] . 因此,在键盘空间中使用字符类更安全。

    第三;尽量不要使用 \s \r \n ). 你提到的情况似乎不赞成这样。然而,正如Omaghosh所指出的,您可能需要的不仅仅是键盘空间。所以你可以用 [ ] [\s-[\r\n]] ,或 [\f\t\v\u00A0\u2028\u2029\u0020]

    第四;这是一种常见的过度构建模式: (\s*...\s*)* . 这没有任何意义。与此相同: (\s*\s*...)* 或者这个: (\s*\s*\s*\s*...)* ... . 但从来没有一次是真正想要的。在最坏的情况下,您可能会看到: \s*(...\s*)*

    奥马霍什得到了最接近的答案,但这是最短的正确答案:

    Regex.Match(input, @"(?:\d[ ]*){8,}").Groups[0].Value;
    

    Regex.Match(input, @"(?m)^(?:\d[ ]*){8,}$").Groups[0].Value;
    

    或者,如果它是更大正则表达式的一部分,并且需要一个组:

    Regex.Match(input, @"...((?:\d[ ]*){8,})...").Groups[1].Value;
    

    可以随意更换 [ ] 对于.NET类减法或非.NET显式空白类:

    @"(?:\d[\s-[\r\n]]*){8,}"
    // Or . . .
    @"(?:\d[\f\t\v\u00A0\u2028\u2029\u0020]*){8,}"
    
        2
  •  13
  •   Amarghosh    14 年前
    (\d *){8,}
    

    ( *\d *){8,}  #there is a space before first asterik
    

    将字符串与开头的空格匹配。或者

    (\s*\d\s*){8,}
    

    最后,让它成为一个非捕获组 ?: . 因此,它成为 (?:\s*\d\s*){8,}

        3
  •  -1
  •   leppie    14 年前
    (\d{8,}\s+)*\d{8,}
    

    应该有用