Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8065554

MatchResult should provide values of named-capturing groups

    XMLWordPrintable

Details

    • Enhancement
    • Resolution: Fixed
    • P4
    • 20
    • 19
    • core-libs

    Description

      A DESCRIPTION OF THE REQUEST :
      Method String group(String name) has been added in class java.util.regex.Matcher since 1.7 to deal with named-capturing groups.
      Unfortunately, interface java.util.regex.MatchResult has not been extended with the same method, even though now it would be possible with a default method without breaking backwards compatibility.
       

      JUSTIFICATION :
      Expressions like matcher.toMatchResult().group("MY GROUP") cannot be typechecked when matcher has static type java.util.regex.Matcher, even though class java.util.regex.Matcher defines method String group(String name)

      Note that toMatchResult() is very useful if one wants the result to be unaffected by subsequent operations performed upon the matcher; for instance, this is necessary if one has to synchronize the matcher with a character stream with methods Matcher region(int start, int end) or Matcher reset(CharSequence input).
      But toMatchResult() is useless if one has to deal with named-capturing groups, because method String group(String name) cannot be invoked on the result of toMatchResult()

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      import java.util.regex.MatchResult;
      import java.util.regex.Matcher;
      import java.util.regex.Pattern;

      public class RequestTest {

         public static void main(String[] args) {
            Matcher matcher = Pattern.compile("(?<NUMBER>[0-9]+)|(?<BLANKS>\\s+)").matcher("42 0");
            matcher.lookingAt();
            MatchResult res = matcher.toMatchResult();
            matcher.region(res.end(), matcher.regionEnd());
            // assert res.group("NUMBER").equals("42"); // this line should compile, and assert should succeed
          }
      }
           
      ACTUAL -
      The commented line in the code snippet above cannot be compiled, as expected, since method group(String name) cannot be found in interface java.util.regex.MatchResult

      ---------- BEGIN SOURCE ----------
      import java.util.regex.MatchResult;
      import java.util.regex.Matcher;
      import java.util.regex.Pattern;

      public class RequestTest {

         public static void main(String[] args) {
            Matcher matcher = Pattern.compile("(?<NUMBER>[0-9]+)|(?<BLANKS>\\s+)").matcher("42 0");
            matcher.lookingAt();
            assert matcher.group("NUMBER").equals("42");
            MatchResult res = matcher.toMatchResult();
            matcher.region(res.end(), matcher.regionEnd());
            // assert matcher.group("NUMBER").equals("42"); // throws java.lang.IllegalStateException
            // assert res.group("NUMBER").equals("42"); // this line should compile, and assert should succeed
          }
      }
          
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      One can either use method String group(int group), but this implies giving up using named-capturing groups, or has to resort to reflection (!).

      import java.lang.reflect.InvocationTargetException;
      import java.util.regex.MatchResult;
      import java.util.regex.Matcher;
      import java.util.regex.Pattern;

      public class RequestReport {

      public static void main(String[] args) throws NoSuchMethodException,
      IllegalAccessException, IllegalArgumentException,
      InvocationTargetException, SecurityException {
      Matcher matcher = Pattern.compile("(?<NUMBER>[0-9]+)|(?<BLANKS>\\s+)").matcher("42 0");
      matcher.lookingAt();
      assert matcher.group("NUMBER").equals("42");
      MatchResult res = matcher.toMatchResult();
      matcher.region(res.end(), matcher.regionEnd());
      assert res.group(1).equals("42");
      assert res.getClass().getDeclaredMethod("group", String.class)
      .invoke(res, "NUMBER").equals("42");
      matcher.lookingAt();
      assert matcher.group("BLANKS") != null;
      }
      }


      Attachments

        Issue Links

          Activity

            People

              rgiulietti Raffaello Giulietti
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: