java regexp得到的不仅仅是需要

时间:2016-01-08 23:31:17

标签: java regex

我有以下regexp

http://[a-z./].*(js)

和字符串

efwefewfhttp://assets.main.com/zepto-1.1.3.min.js fffhttp://assets.main.com/zepto-1.1.3.min.js

代码:

List<String> kk = new ArrayList<String>();

while (urlMatcher.find()){
    kk.add(urlMatcher.group());
}

此正则表达式输出

http://assets.main.com/zepto-1.1.3.min.js fffhttp://assets.main.com/zepto-1.1.3.min.js

但结果中应为2个字符串

如何更改regexp以获得两个字符串作为结果?

1 个答案:

答案 0 :(得分:2)

使用以下带有延迟点匹配模式的正则表达式:

http://[a-z./].*?js
                ^

请参阅regex demo

有了这个,您将匹配http://assets.main.com/zepto-1.1.3.min.jshttp://assets.main.com/zepto-1.1.3.min.js

问题是.*匹配整行,然后回溯,检查它是否可以适应右手模式。因此,它匹配最长的子串(从最左边到最右边)。延迟匹配将匹配从最左侧到下一个子模式的第一次出现,产生2个匹配。

请参阅Watch Out for The Greediness!部分。

另外,由于这些是链接,并且不应该有空格,因此可以使用\S(非空白)速记char类:

http://[a-z./]\S*\.js

此外,文字点可以与\.匹配。请参阅another demo

应尽可能避免懒惰/贪婪点匹配,因为他们可能会涉及大量的回溯!

Sample code

String str = "efwefewfhttp://assets.main.com/zepto-1.1.3.min.js fffhttp://assets.main.com/zepto-1.1.3.min.js";
Pattern ptrn = Pattern.compile("http://[a-z./]\\S*\\.js");
Matcher urlMatcher = ptrn.matcher(str);
List<String> kk = new ArrayList<String>();
while (urlMatcher.find()){
    kk.add(urlMatcher.group());
}
System.out.println(kk);
// [http://assets.main.com/zepto-1.1.3.min.js, http://assets.main.com/zepto-1.1.3.min.js]