最近在做網路爬蟲,需要用到Regex,所以學習一下,先看代碼
public class Main{ public static void main(String[] args){ long start = System.currentTimeMillis(); Scanner in = new Scanner(System.in); //開始正則 String Line = "abcdefg"; String regular = "(b)([\\s\\S]+?)(f)"; System.out.println(getRegular(Line, regular).get(0)); //結束正則 long end = System.currentTimeMillis(); System.out.println("\n用時:"+(end-start)/1000f+"秒"); } private static List<String> getRegular(String line, String regular) { List<String> code = new ArrayList<String>(); Pattern pattern = Pattern.compile(regular); Matcher matcher = pattern.matcher(line); while(matcher.find()){ code.add(matcher.group(1));//問題是這裡的group的參數 } return code; }}
我們的目的是擷取字串Line中的
cde部分,也就是
ab和fg之間的子字串。
這裡不詳解ab([\\s\\S]+?)fg的含義,只要知道是滿足上述要求的Regex即可。
在官方文檔jdk中對group()的定義如下
Stringgroup();//返回由以前匹配操作所匹配的輸入子序列。 Stringgroup(int group); //返回在以前匹配操作期間由給定組捕獲的輸入子序列。 int groupCount(); //返回此匹配器模式中的擷取的群組數。
這裡的擷取的群組數,簡單來說就是,Regex中有多少個括弧,通過groupCount()擷取擷取的群組數
group()和group(0)等價,就是把所有的組數一起擷取,在上面的例子中,正則出來的結果是:bcdef
group(1)表示的是擷取第一組,也就是第一個括弧中的正則出來的字串,在上面的例子中,正則出來的結果是:b
group(2)表示的是擷取第二組,也就是第二個括弧中的正則出來的字串,在上面的例子中,正則出來的結果是:cde
group(3)表示的是擷取第三組,也就是第三個括弧中的正則出來的字串,在上面的例子中,正則出來的結果是:f
那麼問題來了,如果String regular = "b([\\s\\S]+?)f";
把b和f的括弧去掉,結果使用groupCount()擷取的組數為1,而不是之前的3。
也就是說,group(1)擷取的是cde,而不是之前的b。
值得注意的是group()會出現越界問題,要注意。