0

我有这个字符串对象,它由标签(以 [$ 和 $] 为界)和其余文本组成。我试图隔离所有标签。(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 $]

有什么建议为什么会发生这种情况?

4

2 回答 2

3

您应该使用不情愿的量词-".+?"而不是贪婪的- ".+"

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

如果您使用.+,它将匹配除行终止符之外的所有内容,直到最后一个$。请注意,点 ( .)匹配除换行符以外的所有内容。使用不情愿的量词.+?只匹配到$]它遇到的第一个。

在你给定的字符串中,你得到了所有这些匹配,因为你\r\n在两者之间,.+停止匹配。如果你删除所有这些换行符,那么你只会得到一个从 1 st [$到 last的匹配$]

于 2013-07-21T13:14:57.150 回答
0

一个好方法是用否定字符类替换点,例如:

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

(请注意,您不需要转义右方括号)

但也许您只对标签的内容感兴趣:

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

在这种情况下,内容是整个匹配

于 2013-07-21T13:18:09.830 回答