0

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

  • 至少包含 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]

谢谢

4

3 回答 3

0

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

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

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

实现这个的正则表达式:

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

查看这个 Regex101 演示

评论

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

于 2019-07-19T10:58:43.187 回答
0

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

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

演示

详细说明:

~ # 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,}

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

于 2019-07-24T16:34:01.460 回答
0

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

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

关于图案

  • (?<!\S)断言左边的不是非空白字符
  • (?=(?:[^\d\s]*\d){3})断言 wat 在右边是空白字符或数字的 3 倍
  • (?!(?:[^\s-]*-){2})断言右边的不是 2 次空格字符连字符
  • (?!(?:[^\s\\]*\\){2})断言右边的内容不是 2 次空格字符反斜杠
  • [A-Z0-9/\\-]+匹配任何列出的 1 次以上
  • (?!\S)断言右边的不是非空白字符

正则表达式演示

于 2019-07-19T10:32:48.277 回答