我有这个字符串对象,它由标签(由[$和$]限制)和其余文本组成。我试图隔离所有的标签。 (Pattern-Matcher)正确识别所有标签,但其中两个组合成一个。我不知道为什么会发生这种情况,可能是一些内部(Matcher-Pattern)业务。
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 $]
为什么会发生这种情况的任何建议?
答案 0 :(得分:3)
你应该使用不情愿的量词 - ".+?"
而不是贪心 - ".+"
:
"(\\[\\$).+?(\\$\\])" // Note `?` after `.+`
如果您使用.+
,它将匹配除行终结符之外的所有内容,直到最后$
。请注意,点(.
)匹配除换行符之外的所有内容。使用不情愿的量词,.+?
仅匹配它遇到的第一个$]
。
在您给定的字符串中,您获得了所有这些匹配,因为您之间有\r\n
,其中.+
停止匹配。如果您删除所有这些换行符,那么您只需从1 st [$
到最后一个$]
进行一次匹配。
答案 1 :(得分:0)
一个好方法是用否定的字符类替换点,例如:
Pattern p = Pattern.compile("(\\[\\$)([^$]++)(\\$])");
(请注意,您不需要关闭方括号)
但也许您只对标签的内容感兴趣:
Pattern p = Pattern.compile("(?<=\\[\\$)[^$]++(?=\\$])");
在这种情况下,内容是整个匹配