Учитывая регулярное выражение, как я могу узнать из шаблона, какое наибольшее количество полей может быть сопоставлено? - PullRequest
1 голос
/ 28 февраля 2012

Мне нужно знать, исходя из самого регулярного выражения (без каких-либо выборочных данных), какое максимальное количество полей оно может найти.

Например, для выражения

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

Я бы хотел, чтобы какая-то функция принимала это за String (или Pattern) и возвращала 4, а

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

и возврат 3.

Было бы проще, если бы все эти группы были захвачены, но не все, и я хотел бы избежать написания собственного парсера, если это возможно.

1 Ответ

4 голосов
/ 28 февраля 2012

Это очень уродливо, но ... кажется, делает то, что вам нужно:

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

Или добавить неотражающую версию, которая зависит от способности .matcher(String) достичь класса Pattern:

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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...