3

我正在尝试将字符串输入与以下条件匹配:

  1. 第一个字符是唯一的小写英文字母
  2. 接下来的字符是表示从 1500 到 2020 的当前年份
  3. 下一个字符只能是 10 或 100 或 1000
  4. 最后一个字符将是数字 0 到 9

我创建的我认为大部分正确的正则表达式字符串是有解释的:

String validRegex = 
"^"+                                    # start of string
(?=.*[a-z].*[a-z].*[a-z])"+             # Ensure string has only 3 consecutive lowercase English letters
"(?=.*[0-9].*[0-9].*[0-9].*[0-9])"+     # Ensure string has only 4 digits representing year i.e. 2020
"(?=.*([0-9].*[0-9]) | ([0-9].*[0-9].*[0-9]) | ([0-9].*[0-9].*[0-9].*[0-9]))"+ # Ensure 10, 100, or 100 digits
"(?=.*[0-9])"+                          # Ensure last character is a digit 0-9
"(?=\\S+$)"+                             # Ensure string has no whitespace
".{10,12}"+                              # Entire string length must be from 10 through 12 characters
"$";                                     # end of string

有没有一种简单的方法来更新我的正则表达式,以便我只能检测到唯一的连续字符?

4

2 回答 2

3

看:

  • 整个输入(字符串)长度始终为 10 到 12 个字符- ^.{10,12}$但是,在这种情况下,您不需要将其添加到整体模式中,因为下面的所有部分总计允许 10、11 或 12 个字符字符串)
  • 前 3 个字符是 UNIQUE 小写英文字母 ( [a-z]) -^([a-z])(?!\\1)([a-z])(?!\\1|\\2)[a-z]
  • 接下来的 4 个字符代表从 1500 年到 2020 年的当前年份,即 2020 -(?:1[5-9][0-9]{2}|20[01][0-9]|2020)
  • 下一个字符只能是 10、100 或 1000(所以至少 2 个字符(即 10),或最多 4 个字符(即 1000)) -[0-9]{2,4}
  • 最后一个字符将是数字 0 到 9 - [0-9]

加入这些位,你得到

String regex = "^([a-z])(?!\\1)([a-z])(?!\\1|\\2)[a-z](?:1[5-9][0-9]{2}|20[01][0-9]|2020)[0-9]{2,4}[0-9]$";

请参阅正则表达式演示

如果您计划支持小写和大写字母,请在开头添加不区分大小写的修饰符(?i)

String regex = "(?i)^([a-z])(?!\\1)([a-z])(?!\\1|\\2)[a-z](?:1[5-9][0-9]{2}|20[01][0-9]|2020)[0-9]{2,4}[0-9]$";

如果末尾可以有一个字母,而不仅仅是一个数字,您可以使用

String regex = "(?i)^([a-z])(?!\\1)([a-z])(?!\\1|\\2)[a-z](?:1[5-9][0-9]{2}|20[01][0-9]|2020)[0-9]{2,4}[0-9a-z]$";

请参阅此正则表达式演示

要创建正则表达式数字范围,您可以使用诸如gamon.webfactional.comrichie-bendall.mlMyRegexTester.com等知名服务。

请参阅Java 演示

String regex = "(?i)(([a-z])(?!\\2)([a-z])(?!\\2|\\3)[a-z])(1[5-9][0-9]{2}|20[01][0-9]|2020)([0-9]{2,4})([0-9a-z])";
String s = "AVG190420T";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);
if (matcher.find()){
    System.out.println("Part 1: " + matcher.group(1));
    System.out.println("Part 2: " + matcher.group(4));
    System.out.println("Part 3: " + matcher.group(5));
    System.out.println("Part 4: " + matcher.group(6));
} else {
    System.out.println(s + " does not match the pattern.");
}

输出:

Part 1: AVG
Part 2: 1904
Part 3: 20
Part 4: T
于 2020-10-28T12:10:31.890 回答
0

以下正则表达式不使用前瞻,但它似乎通过初始要求更好地验证:

^(abc|bcd|cde|def|efg|fgh|ghi|hij|ijk|jkl|klm|lmn|mno|nop|opq|pqr|qrs|rst|stu|tuv|uvw|vwx|wxy|xyz)(1[5-9]\d{2}|20[0-1]\d|2020)10{1,3}\d$

在线演示

第一(abc|bcd|...|xyz)验证唯一的连续小写字母。

第二组验证年份: 1500-2020(1[5-9]\d{2}|20[01]\d|2020)匹配年份

剩余的数字后缀被验证:

  • 10{1,3}匹配 10、100 或 100
  • \d匹配结束数字

更新
对于年份范围 1900..2019,模式是(19\d{2}|20[01]\d) 对于 10、20、50、100、200、500、1000 等数字,模式是(10{1,3}|[25]0{1,2})

更新的在线演示

于 2020-10-28T12:45:46.103 回答