简体   繁体   中英

Given a regex, how can I know from the pattern what the largest number of fields there are that could be matched?

I need to know, based on the regex itself (without any sample data), what the maximum number of fields it could find is.

For example, for the expression

"^(ABC) ?([0-9]{4}|[0-9]{6})?(?:(?:/)([0-9]{4}|[0-9]{6}))?(?:(?: ?XYZ ?)([0-9]{4}))?$"

I'd like some function that would take that as a String (or a Pattern ) and return 4, and would take

"^(DEF) ?([0-9A-Z]{1,2})(?:(?:/)([0-9A-Z]{1,2}))?$"

and return 3.

It would be simpler if all of these groups were captured, but not all are, and I'd like to avoid having to write my own parser if possible.

This is very ugly but... seems to do what you need:

public class TestRegEx1 {
    public static void main(String[] args) {
        Pattern pat = Pattern.compile("^(ABC) ?([0-9]{4}|[0-9]{6})?(?:(?:/)([0-9]{4}|[0-9]{6}))?(?:(?: ?XYZ ?)([0-9]{4}))?$");
        try {
            Field groupCount = Pattern.class.getDeclaredField("capturingGroupCount");
            groupCount.setAccessible(true);
            int count = ((Integer) groupCount.get(pat)) - 1;
            System.out.println("count : " + count);
        } catch (Exception e) { }
    }
}

Or to add the non-reflective version, which depends on .matcher(String) being able to reach into the Pattern class:

public class TestRegEx2 {
    public static void main(String[] args) {
        Pattern pat = Pattern.compile("^(ABC) ?([0-9]{4}|[0-9]{6})?(?:(?:/)([0-9]{4}|[0-9]{6}))?(?:(?: ?XYZ ?)([0-9]{4}))?$");
        int count = pat.matcher("").groupCount(); // it turns out it doesn't matter what pattern you use here
        System.out.println("count : " + count);
    }
}

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