如何迭代正则表达式
假设我有以下字符串:
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)); }
有没有办法用一个正则表达式做到这一点?
您可以通过以下方式validation和迭代匹配一个正则表达式:
-
确保匹配之间没有不匹配的字符(例如
name1=x;;name2=y;
),在我们的正则表达式的开头放置一个\G
,这意味着“上一个匹配的结束” 。 -
通过将字符串的长度与
Matcher.end()
进行比较来检查我们是否在最后一次匹配时到达字符串的末尾,Matcher.end()
返回最后一个字符匹配后的偏移量。
就像是:
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!");
现场演示 。
某些语言可能允许您直接迭代各个匹配项
^((\\w+)=(\\w+);)*$
,但我不相信你可以用Java做到这一点。
您必须启用“^”和“$”的多行模式才能按预期工作。
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)); } }
注释在哪里,你仍然必须遍历每一行的匹配组,并使外部组成为非捕获组(?:...)
。
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