關於正則表達式的小筆記

關於正則表達式的小筆記

1.1概述

      正則表達式是一種強大而靈活的文本處理工具。使用正則表達式,我們能夠以編程的方式,構造複雜的文本模式,並對輸入的字符串進行搜索。一旦找到了相匹配的部分,就能隨心所欲進行處理。

      在java語言中的正則表達式對反斜槓\有着與其它語言不同的處理。其它語言中,\\表示“想要在正則表達式中插入一個普通的反斜線,沒有任何特殊的意義”;而在java中,\\表示“要插入一個正則表達式的反斜線,因此其後的字符具有特殊的意義。”如:表示一位數字,用\\d表示。

1.2創建正則表達式

表1-1

字符

B

指定字符B

\xhh

十六進制值爲oxhh的字符

\uhhhh

十六進制表示爲oxhhhh的Unicode

\t

製表符Tab

\n

換行符

\r

回車

\f

換頁

\e

轉義(Escape)

      只有學會使用字符類之後,正則表達式的威力才能真正顯現出來。以下是一些創建字符類的典型方式。

表1-2

字符

.

任意字符

[abc]

包含a、b和c的任意字符(和a|b|c作用相同)

[^abc]

除了a、b和c之外的任何字符(否定)

[a-zA-Z]

從a到z或從A到Z的任何字符(範圍)

[abc[hij]]

任意a、b、c、h、i和j字符(和a|b|c|h|i|j作用相同)

[a-z&&[hij]]

任意h、i或j(相交)

\s

空白符(空格、tab、換行、換頁和回車)

\S

非空白符([^\S])

\d

數字[0-9]

\D

非數字[^0-9]

\w

詞字符[a-zA-Z0-9]

\W

非詞字符[^\w]

 

表1-3

邏輯操作符

XY

Y跟在X後面

X|Y

X或Y

(X)

捕獲組,可以在表達式中用\i引用第i個捕獲組

 

表1-4

邊界匹配符

^

一行的起始

$

一行的結束

\b

詞的邊界

\B

非詞的邊界

\G

前一個匹配的結束

 

舉個例子:

public class Demo{

   public static void main(String[] args){

         for(String str:new String[]{"Rudolph","[rR]udolph","[rR][aeiou][a-z]ol.*","R.*"}){

              System.out.println("Rudolph".matches(str));

         }

   }

}

[rR]udolph:r或R開頭;

[rR][aeiou][a-z]ol.*:r或R開頭,第二個字母[aeiou]中一個,第三個[a-z]中一個,後接ol,最後爲任意字符;

R.*:R打頭的任意字符串。

1.3量詞

量詞描述了一個模式吸收輸入文本的方式:

  • 貪婪型:量詞總是貪婪的,除非有其他的選項被設置。貪婪表達式會爲所有可能的模式發現儘可能多的匹配。假如現有模式僅能匹配第一個可能的字符組,如果它是貪婪的,那麼它就會繼續匹配下去。
  • 勉強型:用問號來指定,這個量詞匹配滿足模式所需的最少字符數。所以也稱爲懶惰的、最少匹配的和非貪婪的。
  • 佔有型:這種類型只有在java語言中才可用,當正則表達式被應用於字符串時,它會產生相當多的狀態,以便在匹配失敗時可以回溯。常用於防止正則表達式失控。

貪婪型

勉強型

佔有性

匹配

X?

X??

X?+

一個或零個X

X*

X*?

X*+

零個或多個X

X+

X+?

X++

一個或多個X

X{n}

X{n}?

X{n}+

X恰好出現n次

X{n,}

X{n,}?

X{n,}+

X至少出現n次

X{n,m}

X{n,m}?

X{n,m}+

X至少出現n次,且不超過m次

           注:這裏的表達式X,要使用圓括號括起來,如(abc)+。

1.4Pattern和Matcher

雖然String類中也能使用正則表達式,但其功能有限,所以更願意使用功能強大的regex包下的Pattern.complie()方法來編譯正則表達式。

  1.  會更根據正則表達式生成一個Pattern對象;
  2.   然後將要檢索的字符串傳入Pattern對象的matcher()方法;
  3.   matcher()方法會生成一個Matcher對象。

public class Test{

   public static void main(String[] args){

         for(String str : args){

               Pattern p = Pattern.compile(str);

              Matcher m = p.matcher(args[0]);

              while(m.find()){

                    m.group();

                    m.start();

                    m.end();

              }

         }

   }

}

1.4.1  find()

  Matcher.find()方法可用來在Test中查找多個匹配,find()對字符串進行匹配,匹配到的字符串可以在任何位置。

  find(int i) 重置匹配器,然後嘗試查找匹配該模式、並以指定索引i開始匹配。如下代碼:

@Test

   public void run(){

         String s = "hello world";

         Pattern p = Pattern.compile("\\w+");

         Matcher m = p.matcher(s);

         int i = 0;

         while(m.find(i)){

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

              i++;

         }

   }

/*output

hello

ello

llo

lo

o

world

world

orld

rld

ld

d

*/

1.4.2 組(groups)

Matcher對象提供了一系列方法,用以獲取與組相關的信息:

  • l  int groupCount()返回該匹配器的模式中分組數目;
  • l  String group(int group)返回在以前匹配操作期間由給定組捕獲的輸入子序列。
  • l  int start()返回以前匹配的起始位置的索引。
  • l  int start(int group)返回在以前的匹配操作期間,由給定組所捕獲的子序列的起始索引。
  • l  int end()返回最後匹配字符的索引加一的值。
  • l  int end(int group)返回在前一次匹配操作中,尋找到組的最後一個字符索引加一的值。
  • l  boolean matches()只有在完全匹配正則表達式纔會返回true。
  • l  boolean lookingAt()嘗試將從區域開頭開始的輸入序列與該模式匹配,只要輸入的第一部分匹配就返回true。

1.5split()

split()方法將輸入字符串斷開成字符串對象數組,斷開邊界由下列正則表達式確定:

  • l  String[]split(CharSequence input)圍繞此模式的匹配拆分給定輸入序列。
  • l  String[]split(CharSequence input, int limit)圍繞此模式的匹配拆分給定輸入序列。注:limit可限定通過分割符分割後的字符串數量。

1.6替換操作

  • l  String replaceAll(Stringreplacement)替換模式與給定替換字符串相匹配的輸入序列的每個子序列。
  • l  String replaceFirst(Stringreplacement)替換模式與給定替換字符串匹配的輸入序列的第一個子序列。
  • l  Matcher appendReplacement(StringBuffersb, String replacement)執行漸進式的替換。
  • l  StringBufferappendTail(StringBuffer sb)在執行一次或多次appendReplacement()之後,此方法可以將匹配完後剩下的部分複製到sb中。

1.7reset()

Matcher reset()方法可以重置匹配器,將現有的Matcher對象應用於一個新的字符序列。

1.8Pattern標記

static Pattern compile(String regex, int flags)將給定的正則表達式編譯到具有給定標誌的模式中。

編譯標記

效果

Pattern.CANON_EQ

兩個字符當且僅當它們的完全規範分解相匹配時,就認爲它們是匹配的。例如,如果我們指定這個標記,表達式a\u030A就會匹配字符串?。在默認的情況下,匹配不考慮規範的等價性。

Pattern.CASE_INSENSITIVE(?i)

默認情況下,大小寫不敏感的匹配假定只有US-ASCII字符集中的字符才能進行。這個標記允許模式匹配不必考慮大小寫(大寫或小寫)。通過指定UNICODE_CASE標記及結合此標記。基於Unicode的大小寫不滿乾的匹配就可以開啓了。

Pattern.COMMENTS(?x)

在這種模式下,空格符將被忽略掉,並且以#開始直到行末的註釋也會被忽略掉。通過嵌入的標記表達式也可以開啓Unix的行模式X。

Pattern.DOTALL(?s)

在dotall模式中,表達式"." 匹配所有字符,包括終結符。默認情況下,”." 表達式不匹配行終結符。

Pattern.MULTILINE(?m)

在多行模式下,表達式^和$分別匹配一行的開始和結束。^還匹配輸入字符串的開始,而$還匹配輸入字符串的結尾。默認情況下,這些表達式僅匹配輸入的完整字符串的開始和結束。

Pattern.UNICODE_CASE(?u)

當指定這個標記, 並且開啓CASE_INSENSITIVE時,大小寫不敏感的匹配將按照與Unicode標準相一致的方式進行。默認情況下,大小寫不敏感的匹配假定只能在US-ASCII 字符集中

Pattern.UNIX_LINES(?d)

在這種模式下,在., ^和$行爲中, 只識別行終結符\n

以上表格摘自《java編程思想》

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章