2013-11-12 1 views
0

Я хочу, чтобы разбить входную строку на блоки, начиная с \begin{<word>} и заканчивая \end{<word>} где < слово > может быть «блок», «верс» или «REFR» и сделать addBlock() для каждого блока. При попытке этого метода в строке, содержащей два из этих блоков, m.groupCount() правильно возвращает 2, но m.find() возвращает false. Как это может быть? m.group() выдает исключение.Сличитель groupCount() и найти() не складываются

private void addBlocks(String in) { 
    Pattern p = Pattern.compile("\\\\begin\\{(vers|refr|block)\\}.*\\\\end\\{(vers|refr|block)\\}"); 
    Matcher m = p.matcher(in); 
    while (m.find()) { 
     addBlock(m.group()); 
    } 
} 

Edit: Да, там было несколько вещей неправильно там. Regex - это боль в попке, это не очень интуитивно, и в этом нет никакой разумной помощи. Вот код, который наконец-то работал:.

private void addBlocks(String in) { 
    Pattern p = Pattern.compile("\\\\begin\{(block|vers|refr)\\}(.|$)*?\\\\end\\{(block|vers|refr)\\}", Pattern.DOTALL); 
    Matcher m = p.matcher(in); 
    while (m.find()) { 
     addBlock(m.group()); 
    } 
} 

ответ

0

В общем, ваш код работает для меня, по крайней мере, для этого тестового вызова:

addBlocks("foo bar \\begin{vers}bla\\end{vers}foo bar baz \\begin{refr}bla2\\end{refr} bla"); 

Однако регулярное выражение будет вызывать addBlock() максимум один раз из-за жадных * квантора. Вы могли бы, а хотите использовать *? квантора:

Pattern p = Pattern.compile("\\\\begin\\{(vers|refr|block)\\}.*?\\\\end\\{(vers|refr|block)\\}"); 

С *? квантора вы получите два матча за выше тестовый вызов.

Если совпадения нет на некотором входе, то m.find() будет правильно возвращать false и m.group() не будет называться (и, следовательно, не будет бросать любой IllegalStateException). Независимо от входной строки, m.groupCount() всегда будет равным 2 для вашего обычного регулярного выражения, так как в шаблоне есть 2 группы захвата .

0

Это никогда не будет давать более одного результата из-за *, который ест каждый символ, который предшествует закрывающего тега.

groupCount() не возвращает количество совпадений, но количество групп для захвата. Также описано здесь: https://stackoverflow.com/a/2989061/2947592