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);
    }
}
David Portabella
  • 12,390
  • 27
  • 101
  • 182
  • Reflection would indeed work. Just call `setAccessible` on the `Method` – Salem Jul 21 '17 at 07:47
  • i've updated the question with a example source code to use reflection, but it fails with NoSuchMethodException. any idea? – David Portabella Jul 21 '17 at 08: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. – Jesper Jul 21 '17 at 08:07

1 Answers1

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.

Salem
  • 13,516
  • 4
  • 51
  • 70