如何迭代正则表达式

假设我有以下字符串:

name1=gil;name2=orit; 

我想找到name=value所有匹配项,并确保整个字符串与模式匹配。

所以我做了以下事情:

  1. 确保整个模式符合我的要求。

     Pattern p = Pattern.compile("^((\\w+)=(\\w+);)*$"); Matcher m = p.matcher(line); if (!m.matches()) { return false; } 
  2. 迭代模式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