Ошибка шаблона отладки (регулярное выражение) в Java (Android) - PullRequest
2 голосов
/ 27 марта 2012

Я делаю сопоставление с образцом в куске кода, который отлично работает в одном случае, но не в другом. Код в настоящее время:

DLVRYrx = Pattern.compile("(\\d+\\s\\p{Letter}+\\s\\d+)\\s(\\d+(?:\\.\\d+)?)\\s(\\d+)");
Log.d(TAG, "* Regex matched " + DLVRYrx.matcher("01 Jan 01 60.9876 1234").groupCount() + " groups"); // prints 3 as expected in logcat
for (int i=19; i<(fields-6); i++) {
    final String DATAstr = values[i];
    try {
        Matcher Dmatch = DLVRYrx.matcher(DATAstr);
        String data1 = Dmatch.group(0);
    } catch (IllegalStateException e) {
        Log.e(TAG, "! Text ["+DATAstr+"] didn't match regex");
    }
}

Код создает исключение IllegalStateException в строке Dmatch.group (0). Вывод строки logcat из улова - "01.01.01 60.9876 1234", как указано выше.

Выполнение hexdump для файла данных, в котором я читаю, показывает, что пробелы являются пробелами, как и ожидалось, и без каких-либо случайных символов до или после сопоставляемого текста. Есть предложения по отладке этого?

Я немного изменил код, чтобы проверить само выражение, и теперь я в замешательстве. В цикле я сейчас проверяю, соответствует ли строка сначала шаблону, а затем запускаю ее через скомпилированную версию:

Pattern P = Pattern.compile(DLVRYrxStr);
if(!DATAstr.matches(DLVRYrxStr)) {
    Log.e(TAG, "[" + DATAstr + "] doesn't match regex");
    break;
}
Matcher Dmatch = P.matcher(DATAstr);

К сожалению (?) Шаблон действительно совпадает и, таким образом, падает до строки P.matcher, строки, после которой возникает исключение, когда я пытаюсь прочитать первую подходящую группу:

W/System.err( 1238): java.lang.IllegalStateException: No successful match so far
W/System.err( 1238):    at java.util.regex.Matcher.ensureMatch(Matcher.java:607)
W/System.err( 1238):    at java.util.regex.Matcher.group(Matcher.java:358)

Решение состоит в том, чтобы добавить проверку ".matches ()", как показано ниже:

Matcher Dmatch = DLVRYrx.matcher(DATAstr);
Dmatch.matches();
String data1 = Dmatch.group(0);

Да, я использую это в выражении if в своем коде, но оставляя его свободным, как указано выше, работает нормально.

1 Ответ

5 голосов
/ 27 марта 2012

Ваш DLVRYrx.matcher(...).groupCount() просто говорит вам, что в шаблоне, из которого он был создан, есть 3 подходящие группы.

т.е. (\\d+\\s\\p{Letter}+\\s\\d+), (\\d+(?:\\.\\d+) и (\\d+)

Вам нужно позвонить либо

matcher.matches()

matcher.lookingAt()

или

matcher.find()

До попытки получить matcher.group(0), поскольку эти методы запрашивают Java для анализа строки.

...