我们说我有以下字符串:
name1=gil;name2=orit;
我想查找name=value
的所有匹配项,并确保整个字符串与模式匹配。
所以我做了以下事情:
确保整个模式符合我的要求。
Pattern p = Pattern.compile("^((\\w+)=(\\w+);)*$");
Matcher m = p.matcher(line);
if (!m.matches()) {
return false;
}
迭代模式name=value
Pattern p = Pattern.compile("(\\w+)=(\\w+);");
Matcher m = p.matcher(line);
while (m.find()) {
map.put(m.group(1), m.group(2));
}
有没有办法用一个正则表达式做到这一点?
答案 0 :(得分:31)
您可以通过以下方式验证并迭代匹配一个正则表达式:
通过在我们的正则表达式的开头添加name1=x;;name2=y;
来确保匹配之间没有不匹配的字符(例如\G
),这意味着"the end of the previous match"。
通过将字符串的长度与Matcher.end()
进行比较来检查我们是否已经到达最后一次匹配的字符串末尾,Live demo返回最后一个字符匹配后的偏移量。
类似的东西:
String line = "name1=gil;name2=orit;";
Pattern p = Pattern.compile("\\G(\\w+)=(\\w+);");
Matcher m = p.matcher(line);
int lastMatchPos = 0;
while (m.find()) {
System.out.println(m.group(1));
System.out.println(m.group(2));
lastMatchPos = m.end();
}
if (lastMatchPos != line.length())
System.out.println("Invalid string!");
{{3}}
某些语言可能允许您直接从中搜索单个匹配项
^((\\w+)=(\\w+);)*$
,但我不相信你能用Java做到这一点。
答案 1 :(得分:3)
您必须启用“^”和“$”的多行模式才能按预期工作。
Pattern p = Pattern.compile("^(?:(\\w+)=(\\w+);)*$", Pattern.MULTILINE);
while (m.find()) {
for (int i = 0; i < m.groupCount() - 2; i += 2) {
map.put(m.group(i + 1), m.group(i + 2));
}
}
在正确的评论中,您仍然必须遍历每一行的匹配组,并使外部组成为非捕获组(?:...)
。
答案 2 :(得分:0)
String example = "name1=gil;name2=orit;";
Pattern pattern = Pattern.compile("((name[0-9]+?=(.+?);))+?");
Matcher matcher = pattern.matcher(example);
// verifies full match
if (matcher.matches()) {
System.out.println("Whole String matched: " + matcher.group());
// resets matcher
matcher.reset();
// iterates over found
while (matcher.find()) {
System.out.println("\tFound: " + matcher.group(2));
System.out.println("\t--> name is: " + matcher.group(3));
}
}
输出:
Whole String matched: name1=gil;name2=orit;
Found: name1=gil;
--> name is: gil
Found: name2=orit;
--> name is: orit