提问人:Satish 提问时间:10/16/2023 最后编辑:Wiktor StribiżewSatish 更新时间:10/16/2023 访问量:82
如何在特定关键字后提取与模式匹配的多个值?
How to extract multiple values matching a pattern after a specific keyword?
问:
需要有关如何使用正则表达式的
发短信:
my friends passport numbers are V123456, V123457 and V123458
正则表达式:
(?<=passport)\s*(?:\w+\s){0,10}\s*(\b[a-zA-Z]{0,2}\d{6,12}[a-zA-Z]{0,2}\b)
预期匹配输出:
V123456
V123457
V123458
实际输出:
V123456
答:
0赞
Wiktor Stribiżew
10/16/2023
#1
你不能在这里依赖后视,因为你需要一个无限长度的模式。它受支持,但仅在最近的 Java 版本中受支持。
您可以使用基于 \G
运算符的模式:
(?:\G(?!\A)|\bpassport\b).*?\b([a-zA-Z]{0,2}\d{6,12}[a-zA-Z]{0,2})\b
请参阅正则表达式演示。图案细节:
(?:\G(?!\A)|\bpassport\b)
- 一个完整的单词护照 () 或 () 上一个成功匹配的结束 (\bpassport\b
|
\G(?!\A)
).*?
- 任何零个或多个字符尽可能少(因为模式是用 编译的,可以匹配任何字符,包括换行符)Pattern.DOTALL
.
\b([a-zA-Z]{0,2}\d{6,12}[a-zA-Z]{0,2})\b
- 以零、一个或两个 ASCII 字母开头,然后有 6 到 12 位数字,以零、一个或两个 ASCII 字母结尾的整个单词。
请参阅下面的 Java 演示:
String s = "my friends passport numbers are V123456, V123457 and V123458";
String rx = "(?:\\G(?!^)|\\bpassport\\b).*?\\b([a-zA-Z]{0,2}\\d{6,12}[a-zA-Z]{0,2})\\b";
Pattern pattern = Pattern.compile(rx, Pattern.DOTALL);
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
System.out.println(matcher.group(1));
}
输出:
V123456
V123457
V123458
评论
0赞
Satish
10/16/2023
谢谢,上下文结束后我怎么能忽略。例如:我的朋友的护照号码是V123456的,V123457 V123458他们的签证号码也T123125,在这种情况下,签证号码不应该被提取
0赞
Wiktor Stribiżew
10/16/2023
@Satish 如果您的停用词是已知的,则可以使用脾气暴躁的贪婪令牌:String rx = "(?:\\G(?!^)|\\bpassport\\b)(?:(?!\\bvisa\\b).)*?\\b([a-zA-Z]{0,2}\\d{6,12}[a-zA-Z]{0,2})\\b";
0赞
Satish
10/17/2023
谢谢你按预期工作,一次快速提问,如果模式后面的关键字“T123125是我的签证号码和V123456,V123457和V123458是我的护照号码”,我们是否可以做同样的事情?
0赞
Wiktor Stribiżew
10/17/2023
@Satish 是的,诀窍是一样的,但模式是不同的,请看这个正则表达式演示。String rx = "(?i)\\b([a-z]{0,2}\\d{6,12}[a-z]{0,2})\\b(?=(?:(?!\\bvisa\\b).)*?\\bpassport\\b)";
1赞
Satish
10/24/2023
是的,谢谢你真的很有帮助
评论
?:\G(?!^)(?:, | 和 )|\bpassport 编号为 )([a-zA-Z]{0,2}\d{6,12}[a-zA-Z]{0,2})
这永远不会跳过除由指定分隔符连接的以下数字模式之外的任何内容,并且是有效的。passport numbers are
(?:, | and )