降低正则表达式的界限

时间:2015-08-04 08:14:47

标签: java regex

我已经创建了这个表达式

(?<=&lt;)(.+?)(&lt;|&gt;)(.+?)(?=&gt;)

我认为它会抓住位于&lt;&gt;之间的&lt;&gt;

然而,例如在那种情况下

&lt;#freemarker &lt; template&gt;

它被抓住了

#freemarker &lt; template

而非&lt;

理想情况下,我希望它能够抓住位于&lt;&gt;&lt;#之间的&lt;/#&gt;

为了使其正常工作,应该改变什么?

2 个答案:

答案 0 :(得分:0)

如果你真的需要只匹配&lt;&gt;,我建议利用Java约束宽度的后视:

(?s)(?<=&lt;/?#.{0,1000})(?:&lt;|&gt;)(?=.*?&gt;)

Demo

使用这种方法,假设初始&lt;/?#之后的字符串不长于1000,这对于实际情况应该足够了。

这是IDEONE demo

String s = "&lt;#freemarker &lt; template&gt;";
System.out.println(Arrays.toString(s.split("(?s)(?<=&lt;/?#.{0,1000})(?:&lt;|&gt;)(?=.*?&gt;)")));
}

结果:[&lt;#freemarker , template&gt;]

答案 1 :(得分:0)

在Java中,您始终可以使用Matcher方法start(int group)end(int group)来获取您感兴趣的部分索引。所以只需使用:

(?<=&lt;)(?:.+?)(&lt;|&gt;)(?:.+?)(?=&gt;)

然后matcher.group(1)获取匹配的字符串,或matcher.start(1)matcher.end(1)获取匹配的片段的开始和结束索引。 ?:用于避免捕获您不想在群组中捕获的片段。

Java中的示例:

public class Main {
    public static void main(String[] args){
        String example = "&lt;#freemarker &lt; template&gt;";
        Pattern pattern = Pattern.compile("(?<=&lt;)(?:.+?)(&lt;|&gt;)(?:.+?)(?=&gt;)");
        Matcher matcher = pattern.matcher(example);
        while(matcher.find()) {
            System.out.println(example.substring(matcher.start(1), matcher.end(1)));
        }
    }
}