【问题标题】:Match regular expression specific character quantities in any order以任意顺序匹配正则表达式特定字符数量
【发布时间】:2019-07-19 10:26:14
【问题描述】:

我需要匹配一系列字符串:

  • 至少包含 3 个数字
  • 0 个或多个字母
  • 0 或 1 -(不多)
  • 0 或 1 \(不多)

这些字符可以在字符串中的任何位置。

我目前的正则表达式是:

([A-Z0-9]*[0-9]{3,}[\/]?[\-]?[0-9]*[A-Z]*)

这在以下情况下匹配以下数据。唯一不匹配的是第一个:

02ABU-D9435
013DFC
1123451
03323456782
ADS7124536768
03SDFA9433/0
03SDFA9433/
03SDFA9433/1
A41B03423523
O4AGFC4430

我想也许我对定位的规定太严格了。如何更新此正则表达式以匹配所有可能性?

PHP PCRE

以下内容不匹配:

01/01/2018 [multiple / or -]
AA-AA   [no numbers]

谢谢

【问题讨论】:

  • @Andreas 我把它放在那里,请再看问题:)
  • 抱歉错过了

标签: php regex pcre


【解决方案1】:

一个选项可能是使用前瞻来断言 3 位数字,而不是 2 个反斜杠,而不是 2 次连字符。

(?<!\S)(?=(?:[^\d\s]*\d){3})(?!(?:[^\s-]*-){2})(?!(?:[^\s\\]*\\){2})[A-Z0-9/\\-]+(?!\S)

关于模式

  • (?&lt;!\S)断言左边不是非空白字符
  • (?=(?:[^\d\s]*\d){3}) Assert wat is on the right is 3 times a whitespace char or digit
  • (?!(?:[^\s-]*-){2}) 断言右边的内容不是 2 次空格字符和连字符
  • (?!(?:[^\s\\]*\\){2}) 断言右边的不是 2 倍的空格字符和反斜杠
  • [A-Z0-9/\\-]+ 匹配列出的任何 1 次以上
  • (?!\S)断言右边不是非空白字符

Regex demo

【讨论】:

  • @WiktorStribiżew 谢谢你是对的,我已经更新了。
【解决方案2】:

您的模式可以通过锚定在字符串开头的正/负前瞻来检查:

  • 至少 3 位数字 -> 找到(不一定是连续的)3 位数字
  • 不超过 1 个“-” -> 断言不存在(不一定是连续的)2 个“-”字符
  • 不超过 1 个“/” -> 断言不存在(不一定是连续的)2 个“/”字符
  • 0 个或多个字母 -> 无需检查。

如果满足这些条件,则允许任何内容。

实现这个的正则表达式:

^(?=(([^0-9\r\n]*\d){3}))(?!(.*-){2})(?!(.*\/){2}).*$

查看this Regex101 demo

备注

此解决方案假定每个测试的字符串都位于其自己的行上,即。不只是被空格分隔。 如果字符串由空格分隔,请选择solution of user @TheFourthBird(与此基本相同,但适合空格分隔)

【讨论】:

    【解决方案3】:

    您可以使用捕获组和反向引用将连字符和斜杠的条件测试为同一个前瞻:

    ~\A(?!.*([-/]).*\1)(?:[A-Z/-]*\d){3,}[A-Z/-]*\z~
    

    demo

    详细:

    ~ # using the tild as pattern delimiter avoids to escape all slashes in the pattern
    \A # start of the string
    (?! .* ([-/]) .* \1 ) # negative lookahead:
                            #  check that there's no more than one hyphen and one slash
    
    (?: [A-Z/-]* \d ){3,} # at least 3 digits
    
    [A-Z/-]* # eventual other characters until the end of the string
    \z # end of the string.
    ~
    

    为了更好地理解(如果你不熟悉的话):这三个子模式从同一个位置开始(在这种情况下是字符串的开头):

    \A
    (?! .* ([-/]) .* \1 )
    (?: [A-Z/-]* \d ){3,}
    

    这是可能的,因为前两个是零宽度断言,它们是简单的测试并且不消耗任何字符。

    【讨论】:

      猜你喜欢
      • 2015-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-01
      • 2021-09-28
      • 2021-12-15
      • 2017-06-12
      • 2013-09-27
      相关资源
      最近更新 更多