Java:正則匹配的不同情況(貪婪,勉強): greedy, reluctant, possesive

轉自:http://www.cppblog.com/biao/archive/2010/02/05/107298.html

import java.util.regex.Matcher;

import java.util.regex.Pattern;

public class Test {

	public static void main(String[] args) {

		String str = "<biao><>c<b>";

		Pattern pattern;

		Matcher matcher;

		// 貪婪: 最長匹配 .* : 輸出: <biao><>c<b>

		pattern = Pattern.compile("<.*>");

		matcher = pattern.matcher(str);

		while (matcher.find()) {

			System.out.println(matcher.group());

		}

		// 不知是否非貪婪 .*? : 輸出: <biao>, <>, <b>

		pattern = Pattern.compile("<.*?>");

		matcher = pattern.matcher(str);

		while (matcher.find()) {

			System.out.println(matcher.group());

		}

		// 使用組, 輸出<>裏的內容, 輸出: 'biao', ' ', 'b'

		// 0組代表整個表達式, 子組從1開始

		pattern = Pattern.compile("<(.*?)>");

		matcher = pattern.matcher(str);

		while (matcher.find()) {

			System.out.println(matcher.group(1));

		}

	}

}


 

 

貪婪、勉強和侵佔量詞間的不同

  在貪婪、勉強和侵佔三個量詞間有着細微的不同。

  貪婪(*, ?, +):讀入整個串,從後往前匹配

  勉強(*?, ??, +?):從前往後匹配

  侵佔(*+, ?+, ++):讀入整個串,從前往後匹配,匹配的是整個串
  貪婪量詞之所以稱之爲“貪婪的”,這是由於它們強迫匹配器讀入(或者稱之爲吃掉)整個輸入的字符串,來優先嚐試第一次匹配,如果第一次嘗試匹配(對於整個輸入的字符串)失敗,匹配器會通過回退整個字符串的一個字符再一次進行嘗試,不斷地進行處理直到找到一個匹配,或者左邊沒有更多的字符來用於回退了。賴於在表達式中使用的量詞,最終它將嘗試地靠着 1 或 0 個字符的匹配。
  但是,勉強量詞采用相反的途徑:從輸入字符串的開始處開始,因此每次勉強地吞噬一個字符來尋找匹配,最終它們會嘗試整個輸入的字符串。
  最後,侵佔量詞始終是吞掉整個輸入的字符串,嘗試着一次(僅有一次)匹配。不像貪婪量詞那樣,侵佔量詞絕不會回退,即使這樣做是允許全部的匹配成功。
  爲了說明一下,看看輸入的字符串是 xfooxxxxxxfoo 時。

Enter your regex: .*foo // 貪婪量詞 Enter input string to search: xfooxxxxxxfoo I found the text "xfooxxxxxxfoo" starting at index 0 and ending at index 13. Enter your regex: .*?foo // 勉強量詞 Enter input string to search: xfooxxxxxxfoo I found the text "xfoo" starting at index 0 and ending at index 4. I found the text "xxxxxxfoo" starting at index 4 and ending at index 13. Enter your regex: .*+foo // 侵佔量詞 Enter input string to search: xfooxxxxxxfoo No match found.

  第一個例子使用貪婪量詞.*,尋找緊跟着字母“f”“o”“o”的“任何東西”零次或者多次。由於量詞是貪婪的,表達式的.*部分第一次“吃掉”整個輸入的字符串。在這一點,全部表達式不能成功地進行匹配,這是由於最後三個字母(“f”“o”“o”)已經被消耗掉了。那麼匹配器會慢慢地每次回退一個字母,直到返還的“foo”在最右邊出現,這時匹配成功並且搜索終止。
  然而,第二個例子採用勉強量詞,因此通過首次消耗“什麼也沒有”作爲開始。由於“foo”並沒有出現在字符串的開始,它被強迫吞掉第一個字母(“x”),在 0 和 4 處觸發了第一個匹配。測試用具會繼續處理,直到輸入的字符串耗盡爲止。在 4 和 13 找到了另外一個匹配。
  第三個例子的量詞是侵佔,所以在尋找匹配時失敗了。在這種情況下,整個輸入的字符串被.*+消耗了,什麼都沒有剩下來滿足表達式末尾的“foo”。
  你可以在想抓取所有的東西,且決不回退的情況下使用侵佔量詞,在這種匹配不是立即被發現的情況下,它將會優於等價的貪婪量詞。

發佈了17 篇原創文章 · 獲贊 5 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章