Проблема с поиском в регулярном выражении Java. Контрольная группа не имеет очевидной максимальной длины - PullRequest
0 голосов
/ 05 июля 2019

Мне нужно сопоставить sequence='999' внутри тега <noteinfo> в документе xml с использованием Java RegEx (синтаксический анализатор xml не поддерживается).

Фрагмент xml:

<xmltag sequence='11'>
  <noteinfo noteid='1fe' unid='25436AF06906885A8525840B00805DBC' sequence='3'/>
</xmltag>

Я использую это: (?<=<noteinfo.*)sequence='[0-9999]'(?=/>)

Я ожидаю совпадения по этому вопросу: sequence='3'

Ошибка: java.util.regex.PatternSyntaxException: группа наблюдения неимеют очевидную максимальную длину

Я понимаю, что проблема связана с. * в вспомогательной части.Есть ли альтернативы, чтобы избежать ошибки?

Ответы [ 2 ]

0 голосов
/ 11 июля 2019

никогда не используйте вид сзади, если в этом нет крайней необходимости

Вы можете уменьшить длину вида сзади с помощью фигурных скобок, например. {1,255}.
Ваша проблема разрешима без использования взгляда сзади:
static final Pattern seqpat = Pattern.compile( "<noteinfo[^>]+(?<seq>sequence\\s*=\\s*'[\\d]*')", Pattern.MULTILINE );

прочитать файл с:

Matcher m = seqpat.matcher( s );
while( m.find() )
  System.err.println( m.group( "seq" ) );

Pattern.MULTILINE необходим, если обернута строка noteinfo
seqpat находит (не совпадает!) Любую строку, начинающуюся с <noteinfo и заканчивающуюся >
запрошенная последовательность записана в group( "seq" )
возможно, вам придется иметь дело с пробелами или символами новой строки между sequence, = и идентификатором последовательности '3' - поэтому: \\s*=\\s*

Приведенный выше шаблон находит каждый идентификатор последовательности (даже empy)
чтобы найти только '999' sequence-id, возьмите этот паттерн:
Pattern.compile( "<noteinfo[^>]+(?<seq>sequence\\s*=\\s*'999')", Pattern.MULTILINE );

0 голосов
/ 05 июля 2019

Я предполагаю, что вы можете создать выражение, похожее на:

(?=<noteinfo).*(sequence='[0-9]'|sequence='[1-9][0-9]{0,3}')

DEMO

Test

import java.util.regex.Matcher;
import java.util.regex.Pattern;

final String regex = "(?=<noteinfo).*(sequence='[0-9]'|sequence='[1-9][0-9]{0,3}')";
final String string = "<xmltag sequence='11'>\n"
     + "  <noteinfo noteid='1fe' unid='25436AF06906885A8525840B00805DBC' sequence='3'/>\n"
     + "</xmltag>\n"
     + "<xmltag sequence='11'>\n"
     + "  <noteinfo noteid='1fe' unid='25436AF06906885A8525840B00805DBC' sequence='9999'/>\n"
     + "</xmltag>\n"
     + "<xmltag sequence='11'>\n"
     + "  <noteinfo noteid='1fe' unid='25436AF06906885A8525840B00805DBC' sequence='10000'/>\n"
     + "</xmltag>\n"
     + "<xmltag sequence='11'>\n"
     + "  <noteinfo noteid='1fe' unid='25436AF06906885A8525840B00805DBC' sequence='-1'/>\n"
     + "</xmltag>";

final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);

while (matcher.find()) {
    System.out.println("Full match: " + matcher.group(0));
    for (int i = 1; i <= matcher.groupCount(); i++) {
        System.out.println("Group " + i + ": " + matcher.group(i));
    }
}
...