【问题标题】:Multiple spaces, multiple commas and multiple hypens in alphanumeric regex字母数字正则表达式中的多个空格、多个逗号和多个连字符
【发布时间】:2015-07-22 12:43:20
【问题描述】:

我对正则表达式和正则表达式非常陌生,我陷入了想在 JSF 输入字段上应用正则表达式的情况。

在哪里

  1. 字母数字
  2. 多个空格
  3. 多个点(.)
  4. 多个连字符 (-)

是允许的,下限为 1上限为 5

对于多个值 - 它们必须用逗号 (,) 分隔

所以一个单一的值可以是:

3kd-R

k3

-4

以及多个值(必须用逗号分隔):

kdk30,3.K-4,ER--U,2,.I3,

在stackoverflow的帮助下,到目前为止我只能做到这一点:

(^[a-zA-Z0-9 ]{5}(,[a-zA-Z0-9 ]{5})*$)

【问题讨论】:

    标签: regex


    【解决方案1】:

    有点像

    ^[-.a-zA-Z0-9 ]{1,5}(,[-.a-zA-Z0-9 ]{1,5})*$
    

    所做的更改

    • [-.a-zA-Z0-9 ] 在字符类中添加了-.,以便它们也能匹配。

    • {1,5} 量词,确保匹配最小1 和最大5 字符

    Regex demo

    【讨论】:

      【解决方案2】:

      你做得很好。您需要在第一个字符类中添加连字符和点。注意:使用连字符,因为它代表字符类中的范围,所以您需要将它定位在上下文中它不能指定范围的位置 - 并不是说​​将它放在看起来可能是无效范围的位置,例如,@987654321 @,但 positionally 不能是范围,即第一个或最后一个。所以你的第一个字符类看起来像这样:

      [a-zA-Z 0-9.-]{1,5}[-a-zA-Z0-9 .]{1,5}

      所以,我们刚刚定义了一个细分的样子。该模式可以重复出现零次或多次。当然,有很多方法可以做到这一点,但我更喜欢正则表达式子例程,因为这允许代码重用。现在,如果规格发生变化,或者您正在测试并意识到您必须调整该段模式,您只需在一个地方进行更改

      BRE 或 ERE 不支持子例程,但大多数广泛使用的现代正则表达式引擎都支持它们(Perl、PCRE、Ruby、Delphi、R、PHP)。它们非常简单使用和理解。基本上,您只需要能够引用它(听起来很熟悉?引用返回?反向引用?),所以这意味着我们需要捕获我们希望重复的正则表达式。那么它就像引用它一样简单,但不是引用捕获的(数据)的\1,我们希望将其称为(?1),捕获表达式。为此,我们在逻辑上定义了一个子例程:

      ([a-zA-Z 0-9.-]{1,5})(,(?1))*
      

      所以,第一组基本上定义了我们的子程序,第二组由一个逗号组成,后跟我们用于第一组的相同段定义表达式,即 可选 ('*'是零个或多个量词)。

      如果您在考虑效率的情况下对大量数据进行操作,请不要在不必要时进行捕获。如果您使用括号的唯一目的是交替(例如,\b[bB](asset|eagle)\b hound)或量化,如在我们的第二组中,请使用(?: ... ) 表示法,这向正则表达式引擎表示这是一个非捕获组。无需详细说明,维护匹配位置会产生大量开销——并不是说它本身很复杂,只是可能高度重复。正则表达式引擎将匹配、存储信息,然后当匹配失败时,它们“放弃”匹配并从下一个匹配的子字符串开始重试。每次它们与您的捕获组匹配时,它们都会再次存储该信息。好的,我现在离开肥皂盒了。 :-)

      所以,我们快到了。我说“几乎”是因为我没有所有信息。但是如果这应该是“主题”(行、字段等——您正在评估的数据样本)的唯一占用者,您应该将其锚定为“断言”该要求。插入符号 '^' 是主题的开头,美元 '$' 是主题的结尾,因此通过将我们的表达式封装在 ^ ... $ 中,我们断言主题完全匹配,前面 -背靠背。这些断言的长度为零;他们不消耗任何数据,只声明一个相对位置。您可以对它们进行操作,例如,s/^/ / 会将整个文档缩进两个空格。您并没有真正用两个空格替换行的开头,但是您可以在那个虚构的零长度位置上进行操作。 (对零长度断言 [又名零宽度断言,或环视] 进行一些研究,以发现现代正则表达式的强大功能。例如,在之前的正则表达式中,如果我想确保我没有在空行:s/^(?!$)/ /)

      另外,您没有说是否需要捕获结果以对其进行处理。我的印象是它只是验证,所以没有必要。但是,如果需要,您可以将整个表达式包装在捕获括号中:^( ... )$

      我将提供一个最终解决方案,假设您需要捕获但确实假设整个主题应包含以下值:

      ^([a-zA-Z 0-9. -]{1,5})(?:,(?1))*$
      

      我知道我讲了一点,但你说你是正则表达式的新手,所以想提供一些细节。希望不要太详细。

      顺便说一句,一个很好的教程资源是正则表达式点信息,一个很棒的正则表达式开发和测试工具是 regex101 dot com。关于堆栈溢出,我永远也说不完!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-22
        • 1970-01-01
        • 1970-01-01
        • 2022-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多