2013-07-21 1 views
0

У меня есть этот строковый объект, который состоит из тегов (ограниченных [$ и $]) и остальной текст. Im пытается изолировать все теги. (Pattern-Matcher) правильно распознают все теги, но два из них объединены в один. Я не знаю, почему это происходит, возможно, некоторые внутренние (Matcher-Pattern) бизнес.(Pattern and Matcher), не обнаруживая совпадений всех шаблонов

String docBody = "This is sample text.\r\n[$ FOR i 1 10 1 $]\r\n This is" + 
      "[$ i $]-th time this message is generated.\r\n[$END$]\r\n" + 
      "[$ FOR i 0 10 2 $]\r\n sin([$= i $]^2) = [$= i i * @sin \"0.000\"" + 
      " @decfmt $]" + 
      "\r\n[$END$] "; 

Pattern p = Pattern.compile("(\\[\\$)(.)+(\\$\\])"); 
Matcher m = p.matcher(docBody); 

    while(m.find()){ 

     System.out.println(m.group()); 

      } 

output: 

[$ FOR i 1 10 1 $] 
[$ i $] 
[$END$] 
[$ FOR i 0 10 2 $] 
[$= i $]^2) = [$= i i * @sin "0.000" @decfmt $] 
[$END$]` 

Как вы можете видеть, эта часть [$= i $]^2) = [$= i i * @sin "0.000" @decfmt $] не разложилась на эти два тега [$= i $] и [$= i i * @sin "0.000" @decfmt $]

Любые предложения, почему это происходит?

ответ

3

Вы должны использовать неохотно квантор - ".+?" вместо жадного - ".+":

"(\\[\\$).+?(\\$\\])" // Note `?` after `.+` 

Если вы используете .+, это будет соответствовать все, кроме линии терминатора до последнего $. Обратите внимание, что точка (.) соответствует всем, кроме новой строки. С неохотный квантификатор, .+? всего совпадений только до первого $] он сталкивается.

В данной строке вы получили все эти совпадения, потому что у вас было \r\n между ними, где .+ останавливается. Если вы удалите все эти новые строки, вы получите только один матч от 1 st[$ до последних $].

0

Хороший способ заменить точку на инвертированный класс символов, например:

Pattern p = Pattern.compile("(\\[\\$)([^$]++)(\\$])"); 

(обратите внимание, что вам не нужно, чтобы избежать закрытия квадратных скобок)

Но, возможно, являются вы только заинтересованы в содержании тегов:

Pattern p = Pattern.compile("(?<=\\[\\$)[^$]++(?=\\$])"); 

В этом случае содержание всей ма tch

+0

Почему голос? –

+0

-1 для [^], который a) недействителен в java и b) даже если бы он был действительным, это не решило бы проблему OP, напротив, это сделало бы ее хуже. – Ingo

+0

@Ingo. Это абсолютно справедливо в Java. И возвращает тот же результат, что и OP. Я говорю о первом. –