简体   繁体   中英

How to iterate over regex expression

Let's say I have the following String:

name1=gil;name2=orit;

I want to find all matches of name=value and make sure that the whole string matches the pattern.

So I did the following:

  1. Ensure that the whole pattern matches what I want.

     Pattern p = Pattern.compile("^((\\\\w+)=(\\\\w+);)*$"); Matcher m = p.matcher(line); if (!m.matches()) { return false; }
  2. Iterate over the pattern name=value

     Pattern p = Pattern.compile("(\\\\w+)=(\\\\w+);"); Matcher m = p.matcher(line); while (m.find()) { map.put(m.group(1), m.group(2)); }

Is there some way to do this with one regex?

You can validate and iterate over matches with one regex by:

  • Ensuring there are no unmatched characters between matches (eg name1=x;;name2=y; ) by putting a \\G at the start of our regex, which mean "the end of the previous match" .

  • Checking whether we've reached the end of the string on our last match by comparing the length of our string to Matcher.end() , which returns the offset after the last character matched.

Something like:

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!");

Live demo .

You have to enable multiline-mode for "^" and "$" to work as expected.

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));
    }
}

Comments where right, you still have to iterate through matching groups for each line and make the outer group a non-capturing group (?:...) .

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));
    }
}

Output:

Whole String matched: name1=gil;name2=orit;
    Found: name1=gil;
    --> name is: gil
    Found: name2=orit;
    --> name is: orit

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM