正則表達式---獲取英文雙引號里面的內容
來源 http://blog.csdn.net/u010102284/article/details/17246413
有時我們會很煩惱,怎樣獲取英文 " " 里面的內容,因為英文的前后引號一樣,會造成很多麻煩:
例如:The name "McDon ald's" is said "markudonarudo" in Japanese
String input = "The name \"McDon ald's\" is said \"markudonarudo\" in Japanese";
Pattern p = Pattern.compile("\"(.+)\"");
//由於引號內可能存在空格以及其他除了"各種各樣的字符,我可以使用排除型字符組[^], 但我首先試一下 .+
Matcher m = p.matcher(input);
int count = 0;
while(m.find()){
count ++;
System.out.println(count + "----使用 .:" + m.group(0));
}
結果為:
1----"McDon ald's" is said "markudonarudo"
順着這條思路往下走,我發現我只是多匹配了一些字符,因為 .+ 可以匹配至少一個字符,由於正則的貪婪特性,它從M開始將后面的所有的字符
到Japanese的都全部匹配上了,但是由於
\"(.+)\"
最后還有個 " 結尾所以無法匹配,.+ 會讓出一個字符讓 " 來匹配,如果匹配不上繼續讓出字符,直到匹配成功或者無法讓出宣告匹配失敗
那么好吧,正則太貪婪了,正好有一種懶惰匹配,如示例中的:
String input = "The name \"McDon ald's\" is said \"markudonarudo\" in Japanese";
Pattern p = Pattern.compile("\"(.+?)\"");
//只要在+后面加上一個簡單的?就可以的到正確的結果
Matcher m = p.matcher(input);
int count = 0;
while(m.find()){
count ++;
System.out.println(count + "----使用 .:" + m.group(0));
}
.+?的意思是在匹配的前提下,盡可能少的匹配,怎么樣理解盡可能少,如此例中,.+?本來可以像上一個例子中,匹配一大串,但是由於后面有個?總是催促:“你匹配好了沒有,該我了吧?”,所以,.+心理很煩,變得很懶了,在第一“收尾的時候就停下來了,這樣就得到了正確的結果。
1----使用 .:"McDon ald's"
2----使用 .:"markudonarudo"
現在看看這個懶惰的正則表達式:?放在括號外邊行不行,當然不可以,那樣?就成了最好匹配一次,即使不匹配也可以的元字符,所以懶惰的用法應該是緊跟着貪婪元字符的后面。
還有一點要注意的是使用環視的時候,由於環視不占用字符,只是占用位置
這樣會得到三個答案:
String input = "The name \"McDon ald's\" is said \"markudonarudo\" in Japanese";
Pattern p = Pattern.compile("(?<=\")(.+?)(?=\")");
//使用的是環視
Matcher m = p.matcher(input);
int count = 0;
while(m.find()){
count ++;
System.out.println(count + "----使用 .:" + m.group(0));
}
(?<=")代表這個位置的左邊必須有一個 ” ,既然正則不會占用 “ ,它只需要左邊是 ” 右邊是什么它不會管,這樣我們可以認為它占用了一個什么都不是的縫隙位置,這個縫隙位置只有一個要求就是左邊是 ” ,(?=\")的意思是占用兩個字符之間的縫隙位置,縫隙位置的右邊是“ ,此時由於環視都不會占用字符,而縫隙只是理解,並不存在真正的縫隙,這樣匹配結束后的位置只是到達s 和 ”之間的位置,下一次匹配的時候就會把 “ 也匹配上
1----使用 .:McDon ald's
2----使用 .: is said
3----使用 .:markudonarudo
所以使用環視有點不妥!
//還可以使用以下方式的排除環視
Pattern p = Pattern.compile("\"((?!\").)+\"");
//(?!\").的意思是一個位置的右邊不能是" ,然后后面接了一個. ,就是說.表示的其他字符都行,就是不能是"