提问人:Ivan Karotki 提问时间:11/14/2023 最后编辑:Ivan Karotki 更新时间:11/14/2023 访问量:87
Java 正则表达式模式数学无效可选部分
Java regex pattern mathes not valid optional part
问:
我在代码中有以下正则表达式模式:
"(?<part1>(?<year>\\d{4})(?<day>\\d{3})(?<number>[A-Z0-9]{3})(?<sequence>\\d{4}))-(?<lastPart>(?<letter>[A-Z0-9]+)_?(?<num1>\\d+)?_?(?<num2>\\d+)?)"
我已将其更改为以下内容,使其成为可选的:<lastPart>
"(?<part1>(?<year>\d{4})(?<day>\d{3})(?<number>[A-Z0-9]{3})(?<sequence>\d{4}))-?(?<lastPart>(?<letter>[A-Z0-9]+)_?(?<num1>\d+)?_?(?<num2>\d+)?)?"
我正在更新它,因为 14 位字符串也是有效的,但是运行测试我发现无效字符串
20221239990001_AB
20221239990001_ABC#$%
20221239990001_+AB><
20221239990001_-*AB___
20221239990001_AB12232434
也是有效的,这是错误的。
如何让我的正则表达式模式验证 14 位字符串作为第一部分,如果之后出现的内容,它应该看起来像谢谢。
编辑1:-{numbers/letters}_{numbers}_{numbers}
不匹配:
2022123999000
202212399900
2022123999
但奇怪的是匹配。12321324143432142352546534636534343243525425
编辑2: 可选部件包含可选子部件 所以:
12233255555555 valid
12233255555555- invalid
12233255555555-A valid
12233255555555-A_ invalid
12233255555555-A_1 valid
12233255555555-A_1_ invalid
12233255555555-A_1_1 valid
12233255555555-A__1 invalid
12233255555555-A__ invalid
答:
1赞
Bohemian
11/14/2023
#1
您的示例在第一部分之后有一个下划线,但您的正则表达式有一个连字符,因此我通过假设您的示例是正确的来纠正该错误。_
-
正则表达式的主要问题是:
- 您已将可选部件的所有子部件设置为可选 - 它们不应是可选的。整个可选部分应该存在或不存在。
- 分隔符(下划线/连字符)必须是可选组的一部分。根据对它的编码方式,无论最终的可选组是否存在,它都是在第一部分之后必填的。
试试这个:
^(\d{4})(\d{3})([A-Z0-9]{3})(\d{4})(_([A-Z0-9]+)_(\d+)_(\d+))?$
观看现场演示。
为了便于阅读,我删除了所有组名称。
我还添加了,因为我不知道你如何使用它。如果您使用的是 ,则可以删除这些内容。^
$
String#matches()
评论
0赞
Ivan Karotki
11/14/2023
您好,最终得到了类似以下内容的内容,它工作正常,除了一种情况:超过 14 位数字的字符串 (1232132414323134242342423) 仍然有效。regex101.com/r/BJItcS/1^(\d{4})(\d{3})([A-Z0-9]{3})(\d{4})(-?([A-Z0-9]+)(_?(\d+))?(_?(\d+))?)?$
1赞
Reilas
11/14/2023
#2
"...我已将其更改为以下,使
<lastPart>
可选...
。奇怪的是12321324143432142352546534636534343243525425
匹配。
从技术上讲,该模式应包括单词边界或一些要锚定的静态值。
"...如何让我的正则表达式模式验证 14 位字符串作为第一部分,如果后面出现的内容,它应该看起来像 -{数字/字母}_{数字
}_{数字}
......”
下面是一个示例,省略了组名称。我在本文末尾包含了完整的模式。
\b(\d{4})(\d{3})([A-Z\d]{3})(\d{4})(?:-([A-Z\d]+)(?:_(\d+)(?:_(\d+))?)?)?(?: |$)
下面是一个示例应用程序。
String r = "\\b(?<part1>(?<year>\\d{4})(?<day>\\d{3})(?<number>[A-Z\\d]{3})(?<sequence>\\d{4}))(?:-(?<lastPart>(?<letter>[A-Z\\d]+)(?:_(?<num1>\\d+)(?:_(?<num2>\\d+))?)?))?(?: |$)";
String s = "12233255555555 valid\n"
+ "12233255555555- invalid\n"
+ "12233255555555-A valid\n"
+ "12233255555555-A_ invalid\n"
+ "12233255555555-A_1 valid\n"
+ "12233255555555-A_1_ invalid\n"
+ "12233255555555-A_1_1 valid\n"
+ "12233255555555-A__1 invalid\n"
+ "12233255555555-A__ invalid";
Pattern p = Pattern.compile(r);
Matcher m = p.matcher(s);
int i = 0;
while (m.find()) {
System.out.println("match " + ++i);
for (String k : m.namedGroups().keySet())
System.out.printf(" %s = '%s'%n", k, m.group(k));
System.out.println();
}
输出
match 1
year = '1223'
lastPart = 'null'
number = '555'
letter = 'null'
day = '325'
num1 = 'null'
part1 = '12233255555555'
sequence = '5555'
num2 = 'null'
match 2
year = '1223'
lastPart = 'A'
number = '555'
letter = 'A'
day = '325'
num1 = 'null'
part1 = '12233255555555'
sequence = '5555'
num2 = 'null'
match 3
year = '1223'
lastPart = 'A_1'
number = '555'
letter = 'A'
day = '325'
num1 = '1'
part1 = '12233255555555'
sequence = '5555'
num2 = 'null'
match 4
year = '1223'
lastPart = 'A_1_1'
number = '555'
letter = 'A'
day = '325'
num1 = '1'
part1 = '12233255555555'
sequence = '5555'
num2 = '1'
这是完整的模式。
\b(?<part1>(?<year>\d{4})(?<day>\d{3})(?<number>[A-Z\d]{3})(?<sequence>\d{4}))(?:-(?<lastPart>(?<letter>[A-Z\d]+)(?:_(?<num1>\d+)(?:_(?<num2>\d+))?)?))?(?: |$)
评论
^\d{14}(?:-[a-zA-Z0-9]+_\d+_\d+)?$
-
_