引言
記得幾年前在做網頁爬蟲后的信息抽取時,針對網頁
源碼中隱藏的要提取的信息,比如評論、用戶信息等屬性信息,直接利用HtmlParser得到。如此做倒是簡單,不過利用的是網頁的規范的tag標記。其實java中的正則表達式也可以用來實現這一功能。而且對於非tag的一些有規律的系列組合的字符串,正則表達式更能夠發揮其卓越的功能。大學時候曾經就接觸過正則表達式,不過只是略知皮毛。現在也無心學習,上面的鏈接網頁有一個比較清晰的介紹可供參考。下面只是陳述一下自己在實驗過程中利用正則表達式來進行模式匹配以抽取目標信息的嘗試及一些簡單發現。
捕獲組
模式中用()來表示捕獲組,並且根據圓括號從左到右來編號。一個給定的正則表達式完整部分編號為0,然后()從左到右分別從1開始計數。我們可以得到任意捕獲組的內容,下面用一個例子來展示:
[java]
public static void main(String[] args) {
// TODO Auto-generated method stub
String stmt = "xx[new Date('08/24/2013'), 9.39],[new Date('08/24/2013'), 9.39],";
String regex = "\\[(.*?)\\],";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(stmt);
System.out.println(m.groupCount());
while(m.find()){
System.out.println(m.group(0));
System.out.println(m.group(1));
}
}
輸出結果為:
[plain
1
[new Date('08/24/2013'), 9.39],
new Date('08/24/2013'), 9.39
[new Date('08/24/2013'), 9.39],
new Date('08/24/2013'), 9.39
根據這,我們可以看到整個的表達式為捕獲組0,可以匹配輸出符合整個表達式模式的串。而()里面的捕獲組則得到相應的匹配內容。
量詞
同樣上面的代碼,當我們將正則表達式中的?去掉后,輸出結果為:
[plain] view plaincopy
1
[new Date('08/24/2013'), 9.39],[new Date('08/24/2013'), 9.39],
new Date('08/24/2013'), 9.39],[new Date('08/24/2013'), 9.39
則發現匹配的是全局部分,也就是所謂的貪婪策略。這就是由於貪婪、勉強和侵占量詞的不同。詳情可以參考:http://www.java3z.com/cwbwebhome/article/article8/Regex/
Java.Regex.Tutorial.
html#reg5_3
因此,我個人認為如果用來信息抽取可能更多的用的是勉強量詞。
嵌套模式?
假若我們抽取的模式里面包括很多頻繁的子模式,是否能夠用一個正則表達式來完成呢?比如針對上面的事例,如果將正則表達式修改為
[java]
String stmt = "xx[[new Date('08/24/2013'), 9.39],[new Date('08/24/2013'), 9.39],];";
String regex = "\\[(\\[(.*?)\\],)*\\];";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(stmt);
System.out.println(m.groupCount());
while(m.find()){
System.out.println(m.group());
System.out.println(m.group(0));
System.out.println(m.group(1));
System.out.println(m.group(2));
}
目前還沒有有效的辦法獲取最內層捕獲組的匹配串,算是一個問題吧?雖然我們可以先用一個正則提取重復部分,然后再利用正則將其分解,一步不行嗎?
Tips
1. .默認並不匹配所有的字符,例如換行空白的就不可以,這時候可以用Pattern p = Pattern.compile(regex,Pattern.DOTALL);來使其匹配所有
