使用正则表达式确定逗号分隔值是否有效

Determine if comma separated values are valid using regex

我有一个用逗号分隔的字母数字值的字符串。如果这些值的长度恰好是 2 个字符,并且至少有 1 个字母字符,则这些值被认为是有效的。如果所有值都有效,那么我想 "capture" 包括逗号在内的整个字符串。如果缺少一个值(背对背逗号),则整个字符串无效。我只能为此使用正则表达式。空白被忽略,使用的编程语言是Java

例子

好的,所以我们的想法是让三个组与 or

相连
(Alpha Digit or Digit Alpha or Alpha Alpha)

然后我们将在末尾允许空格

whitespace zero or more (Alpha Digit or Digit Alpha or Alpha Alpha) whitespace zero or more

最后,我们将重复这 4 次,中间用逗号分隔。

我会使用以下表达式暴力破解这个

((\d[A-Z]|[A-Z]{2}|[A-Z]\d),\s)*(\d[A-Z]|[A-Z]{2}|[A-Z]\d),?$

这是一个细分:

在你的情况下,有 2 个字符在 3 个特定情况下有效

\d[A-Z]|[A-Z]{2}|[A-Z]\d
    - \d[A-Z] - digit followed by uppercase A-Z characters
    - [A-Z]{2} - 2 uppercase A-Z characters
    - [A-Z]\d - uppercase A-Z character followed by a digit

然后以此为基础,我做了一个表达式,表示我需要在这组案例后跟一个逗号和一个 space 0 次或更多次

(                               - start group
    (\d[A-Z]|[A-Z]{2}|[A-Z]\d)  - group as explained above
    ,\s                         - followed by comma and space
)*                              - entire group 0 or more times

然后我用相同的表达式跟随它,但添加了一些额外的修饰符

(                               - start group
     \d[A-Z]|[A-Z]{2}|[A-Z]\d   - group as explained above
)                               - end group
,?                              - 0 or 1 trailing comma
$                               - match end of line

可能有一种更优雅的方式来执行此表达式,但这种方式看起来非常简单。下面是一些 java 的使用示例。

String expression = "((\d[A-Z]|[A-Z]{2}|[A-Z]\d),\s)*(\d[A-Z]|[A-Z]{2}|[A-Z]\d),?$";

System.out.println("3F, 4B, AA, A4B".matches(expression)); // false
System.out.println("3F, 4B, 55, A4".matches(expression)); // false
System.out.println("3F, 4B, 5A, A4".matches(expression)); // true
System.out.println("3F, 4B,,".matches(expression)); // false
System.out.println("3F, 4B, AA, A".matches(expression)); // false
System.out.println("3F, 4B, AA,".matches(expression)); // true

有很多非常好的网站可以让您在浏览器中测试正则表达式并立即获得反馈。这是构建和测试正则表达式的好方法,很多时候页面上什至有一个很好的解释,告诉您您编写的表达式。

尽管其中许多网站不提供 Java 表达式评估环境,但大多数语言都具有相同或非常接近相同的正则表达式规范。为了构建这个表达式,我在 Java 脚本中测试了它,然后在 java 中测试了它 运行 以确保它有效。这是已保存表达式的 link,因此您可以自己测试 https://regex101.com/r/uP4oY2/1

首先,您可以将有效格式简化为 [Alpha+Digit][Alpha] 或 [Alpha][Alpha+Digit]:

String regex = "[a-zA-Z][a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z]"

然后你想在它周围允许任意数量的空格:

String regex = "\s*([a-zA-Z][a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z])\s*"  

你希望它后面跟一个逗号,除非它是字符串的末尾:

String regex = "\s*([a-zA-Z][a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z])\s*(,|$)"  

并且此模式可以重复任意次数(一次或多次):

String regex = "(\s*([a-zA-Z][a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z])\s*(,|$))+"  

您可以尝试以下正则表达式:

^((\s+)??(\d[a-z]|[a-z]\d|[a-z]{2}),?)+?$

此正则表达式可在 java 中用作

boolean foundMatch = text.matches("(?ismd)^((\s+)??(\d[a-z]|[a-z]\d|[a-z]{2}),?)+?$");

测试用例:

3F, 4B, AA, C5              // true
3F, 4B, AA, C5,             // true
3F, 4B, AA, C5,,            // false
3F, 4B, A, C5               // false
3F, 4B, AA, C5, 45, A4B     // false