<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    paulwong

    Regular Expression in Java

    1. Introduction

    正規(guī)表示式(Regular Expression, 以下簡稱 regexp)在文字處理方面, 已經受到廣泛的應用。而各種程式語言中也幾乎都有提供對 regexp 的支援, 廣受歡迎的 Perl 更是其中的佼佼者。在 Java SDK 1.4 版釋出之前, 若想在 Java 語言中使用 regexp, 就必需依靠由第三方提供之類別函式庫(Third-Party Class Library), 例如 The Apache Jakarta Project 提供的 Jakarta Regexp, 及 GNU Regex for Java 等. 而 Sun 也終於在 Java SDK 1.4 以來開始於其核心 API 中提供 java.util.regex.Pattern 等相關類別, 以提供C0D; regexp 的支援。本文將會介紹前述的三種 regexp package 之使用方法, 希望能提供讀者在 Java 中使用 Regular Expression 的指引。注意, 本文中並不會介紹 regexp 的語法, 若要學習 regexp, 請參考附錄。

    2. java.util.regex.*

    JDK 1.4 中所提供的 regex package 中只有簡單的兩個類別, Pattern 及 Matcher。但這兩個物件已經包含了所有 regexp 的功能, 請看以下的介紹:

    2.1 Pattern 與 split()

    Pattern 類別並沒有建構式(Constructor), 若要使用此一類別, 可運用 Pattern.compile(String regex) 方法(method)。例:

    Pattern?p?=?Pattern.compile("a*b");

    注意若傳入的regexp string有錯誤, compile() 會丟出 PatternSyntaxException, 因此必需自行使用try ... catch 加以處理。
    產生出 Pattern 物件後, 要如何使用呢? 先看看 Pattern 提供的方法 split()。此一方法可以將輸入字串中依符合Pattern的位置進行分段, 如:

    String[]?result?=?p.split("123aba23aabc");
    ????
    for?(int?i?=?0;?i?<?result.length;?i++)?{
    ????????System.out.println(?(i?
    +?1)?+?":?"?+?result[i]);
    ????}

    輸出的結果為:

    	1: 123
    2: a23
    3: c

    2.2 Matcher 與 matches()

    Regular Expression 的功能當然不只如此, 但是 Pattern 類別中只提供了split(), 若要進行比對(match)及取代(replace)則必需靠 Matcher 類別。例如要檢驗輸入字串是否合於Pattern, 可以使用 Pattern 中的靜態(tài)方法 matches:

    System.out.println(Pattern.matches("a*b",?"aaaaab"));

    輸出結果為:

    	true

    此一靜態(tài)方法是為了方便使用而提供的簡化方法, 其作用等同以下程式:

    Pattern.compile("a*b").matcher("aaaaab").matches();

    另外, 要注意的是, matches() 是完整字串的比對,所以 Pattern.matches("a*b", "aaaaab") 的傳回值為 true 。但是 Pattern.matches("a*b", "aaaaab1") 則會傳回否。因此, 若要在輸入字串中進行部分比對,則必需使用 Matcher 物件中提供的 method。而要如何取得 Matcher 物件呢? 方法如下:

    Pattern?p?=?Pattern.compile("a*b");
    Matcher?matcher?
    =?p.matcher("aaaaab");

    Matcher 中提供了三種比對方法, 您可以依照實際需要來選擇使用:

    • matches: 完整比對, 整個輸入字串必需符合 regexp。例如前例輸入字串 "aaaaab" 完全符合 "a*b", 因此會 matches() 傳回 true.
    • lookingAt: 從輸入字串開頭比對。如前例, 若輸入字串改為 "aaaaab1" 則 matches() 會傳回 false, 而 lookingAt() 會傳回true。
    • find: 從字串中任意位置開始比對,也就是部分比對。如前例, 若輸入字串改為 "22aaaaab1" 則 matches()及l(fā)ookingAt()皆傳回 false, 而 find() 則會傳回true。

    2.3 replaceFirst(), replaceAll()

    除了比對之外, 取代(replace)也是regexp的常見用途之一, 在 Matcher 中也提供了 replaceFirst() 及 replaceAll() 等方法進行取代。如:

    Pattern?p?=?Pattern.compile("a*b");
    ????Matcher?matcher?
    =?p.matcher("123aaaaab456abcdef");
    ????System.out.println(matcher.replaceFirst(
    "_"));????
    ???????
    //1
    ????matcher.reset();
    ???????
    //2
    ????System.out.println(matcher.replaceAll("_"));
    ???????
    //3


    前例中的 1 會輸出:

    123_456abcdef

    只將第一個 match 的 pattern 取代為 "_", 而 3 則會輸出

    123_456_cdef

    將輸入字串中所有合於 pattern 的字串取代為 "_"。 請注意到 2 的部分呼叫了 matcher.reset(), 此一方法可以讓 Matcher 的比對重新開始, 也就是從輸入字串的開頭開始比對。另外, 若在程式中需要以同一個 Pattern 比對不同的輸入字串, 只需使用 reset(<input>) 方法便可以比對新的輸入字串。

    2.4 gourp(), start() 及 end()

    Matcher還有更進階的用法, 例如群組(Grouping), 在 Matcher 中亦有提供, 請參考以下片段:

    ????Pattern?p?=?Pattern.compile("(\\w+)\\s*=\\s*(\\d+)");
    ????Matcher?matcher?
    =?p.matcher("abc?=?123");
    ????System.out.println(
    "find:?"?+?matcher.find());
    ????System.out.println(
    "groupCount():?"?+?matcher.groupCount());
    ????
    //1
    ????for?(int?i?=?1;?i?<=?matcher.groupCount();?i++)?{
    ????
    //2
    ??????System.out.println("group("?+?i?+?"):"?+?matcher.group(i));?
    ??????System.out.println(
    "start("?+?i?+?"):"?+?matcher.start(i));
    ??????System.out.println(
    "end("?+?i?+?"):"?+?matcher.end(i));
    ????}
    ????matcher.reset();
    ????System.out.println(matcher.replaceFirst(
    "$2?=?$1"));
    ????
    //3

    在 regexp 中, 小括號表示群組, 可以在比對之後, 將合於 pattern 的部分紀錄起來, 以便使用 Matcher 中的 gourp() 及相關方法來應用。前例中的 1 呼叫了 groupCount(), 此處會輸出 2 表示 Pattern 中有兩個群組。迴圈 2 會依序印出各 group 的內容, 結果如下:

    	group(1):abc

    start(1):0

    end(1):3

    group(2):123

    start(2):6

    end(2):9

    注意此處的迴圈由 1 開始, 因為 gourp(0) 所代表的是整個合於 pattern 的輸入字串, 以前例而言就是 "abc = 123", start(0) 與 end(0) 則分別為 0 與 9。
    在 Matcher 提供的取代方法( replaceFirst 與 replaceAll )中, 可以使用"回溯參照", 也就是用 $n 來代表找到的群組編號, 如前例中的 3, 其輸出結果為:

    123 = abc

    2.5 比對參數旗標 (Matching flags)

    熟悉 regexp 的讀者一定會覺得奇怪, 如何建立"與大小寫無關(Case-insensitive)" 的比對樣式呢? 又要怎麼在建立的時候, 指定讓 "." 能符合換行字元呢? 有兩種方式, 第一種方法為在建立 Pattern 物件時傳入比對參數旗標, 如:

    ????Pattern?p?=?Pattern.compile("A.b",?Pattern.DOTALL?|?Pattern.CASE_INSENSITIVE);????//1
    ????Matcher?matcher?=?p.matcher("aaa\nbbb");
    ????System.out.println(matcher.replaceAll(
    "_"));

    如此一來, 前例的輸出會是: aa_bb 另一種方法, 則是使用"內嵌式旗標(Embedded flags)", 也就是將旗標直接加在 regexp 字串中, 如前例中的 1 可以改為以下的寫法:

    Pattern?p?=?Pattern.compile("(?si)A.b");

    其中的 ?s 代表單行模式(single-line mode), 也就是 Pattern.DOTALL; 而 ?i 則代表與大小寫無關, 即 Pattern.CASE_INSENSITIVE。事實上,Pattern可接受的旗標共有 7 種, 也都有其對應的內嵌式旗標, 請參考 JDK 1.4 文件。

    最後, 在 JDK 1.4 中, 之前介紹的 split, matches, replaceAll 及 replaceFirst 等 regexp 功能已經整合到 String 物件中了, 例如要將 "abc123abc" 字串中所有的 "a" 或 "b" 取代為 "c", 可以使用以下敍述:

    ????String?tmp?=?"abc123abc";
    ????String?noab?
    =?tmp.replaceAll("(a|b)",?"c");

    若程式中不需要使用到更進階的 regexp 功能, 便可以多加利用在 String 物件中的這些方法。詳細用法請參考 JDK 1.4 文件。

    3. To be continue...

    以上介紹了 JDK 1.4 中內建的 Regular Expression 類別使用方法, 下期將會介紹 Jakarta Regexp 及 GNU Regex for Java 等套件

    4. 附錄:

    本文所提到的套件參考文件可以在以下 URL 找到:

    1. java.util.regex API Documents, http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/package-summary.html
    2. Regular Expressions for Java, http://www.cacas.org/java/gnu/regexp/
    3. Jakarta Regexp, http://jakarta.apache.org/regexp/index.html

    有關 Regular Expressions 的學習, 可以參考以下文件:
    1. Mastering Regular Expressions, http://www.oreilly.com/catalog/regex/
    2. Manual pages of Perl, perlrequick(1), perlretut(1), perlre(1)
    3. Regular Expression 簡介, http://phi.sinica.edu.tw/aspac/reports/94/94019/
    4. 一輩子受用的 Regular Expressions -- 兼談另類的電腦學習態(tài)度, http://www.cyut.edu.tw/~ckhung/b/gnu/regexp.shtml
    5. A Tao of Regular Expressions (正規(guī)表示式之道) http://sitescooper.org/tao_regexps.html

    posted on 2006-08-23 21:42 paulwong 閱讀(1264) 評論(0)  編輯  收藏 所屬分類: J2SE

    主站蜘蛛池模板: 亚洲av成人一区二区三区在线观看| 亚洲 日韩经典 中文字幕| 蜜臀91精品国产免费观看| 永久免费av无码入口国语片| 国产AV日韩A∨亚洲AV电影| 亚洲av永久无码嘿嘿嘿| 亚洲av伊人久久综合密臀性色| 无码专区一va亚洲v专区在线 | 亚洲成人免费在线| 免费人成网站永久| 亚洲精品乱码久久久久久V| 亚洲综合色一区二区三区小说| 在线观看亚洲精品国产| 亚洲XX00视频| 成人免费无码精品国产电影| 日本在线高清免费爱做网站| 日韩免费无码一区二区三区 | 亚洲国产aⅴ综合网| 性色av免费观看| 日本三级2019在线观看免费| 久久国产精品成人片免费| 黄色免费在线网站| 日本一区午夜艳熟免费| 中文字幕av无码不卡免费 | 亚洲色精品aⅴ一区区三区| 亚洲国产精品丝袜在线观看| 日韩亚洲精品福利| 亚洲av高清在线观看一区二区 | 久久91亚洲精品中文字幕| 国产亚洲精品久久久久秋霞| 亚洲VA综合VA国产产VA中| 爱情岛论坛网亚洲品质自拍| mm1313亚洲精品无码又大又粗| 国产又长又粗又爽免费视频 | 亚洲第一永久在线观看| 青青草原精品国产亚洲av| 亚洲视频日韩视频| 亚洲乱码中文字幕小综合| 国产成人亚洲精品| 日韩欧美亚洲中文乱码| 羞羞漫画页面免费入口欢迎你|