1

java.util.regex.Pattern has a method Map<String, Integer> namedGroups(). For some reason they decided to make it private, and so there is no way to obtain this very useful information! :(

I've tried accessing this information (read-only) with this helper class:

package java.util.regex;

import java.util.Collections;
import java.util.Map;

public class PatternHelper {
    public static Map<String, Integer> getNamedGroups(Pattern pattern) {
        return Collections.unmodifiableMap(pattern.namedGroups());
    }
}

But Java8 complains with java.lang.SecurityException: Prohibited package name: java.util.regex.

How can I access this information (read-only)? maybe by reflection?


Update This program using reflection fails. Any idea?

import java.lang.reflect.Method;
import java.util.regex.Pattern;

public class Test50 {
    public static void main(String[] args) throws Exception {
        Pattern p = Pattern.compile("(?<word>\\w+)(?<num>\\d+)");
        Method method = Pattern.class.getMethod("namedGroups");  // it fails with NoSuchMethodException: java.util.regex.Pattern.namedGroups()
        method.setAccessible(true);
        Object result = method.invoke(p);
        System.out.println("result: " + result);
    }
}
3
  • Reflection would indeed work. Just call setAccessible on the Method Commented Jul 21, 2017 at 7:47
  • i've updated the question with a example source code to use reflection, but it fails with NoSuchMethodException. any idea? Commented Jul 21, 2017 at 8:00
  • You get that error because it is not allowed to create your own classes in a package that starts with java. You could do this with reflection, but beware that you are then directly accessing the internals of class Pattern, which is an ugly hack and which is not guaranteed to still work on future versions of Java. Commented Jul 21, 2017 at 8:07

1 Answer 1

1

getMethod will only find public methods.

Try:

Pattern p = Pattern.compile("(?<word>\\w+)(?<num>\\d+)");
Method method = Pattern.class.getDeclaredMethod("namedGroups");
method.setAccessible(true);
Object result = method.invoke(p);
System.out.println("result: " + result);

Prints: result: {word=1, num=2}

Additionally, looking through grepCode seems to show that namedGroups did not exist before JDK 7 (at least in OpenJDK) so that might factor in as well. I would take caution with such a solution as this is not public API and this functionality is therefore not guaranteed to stay the same in future releases.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.