如何使用正規表示法-2

在如何使用正規表示法-1當中,
我們簡單介紹了單一字元處理的方式,
但是其實還有許多用法沒有解釋到,
例如 特殊字元(空白, 問號, 底線...等等)、字串、重複的字元之類的。
所以接下來要循序漸進的將這些一一解說完畢。


如果我們想要找出任一字元, 那麼就必須使用'.'這個符號,
String htmlCode = 
   "If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, " +
   "then multiplication gives an area for the rectangle of 5.6088 square meters.";
Pattern pattern = Pattern.compile(".");
Matcher matcher = pattern.matcher(htmlCode);
while(matcher.find()) {
    System.out.print(matcher.group());
}
這樣的結果就會出現整段字串,
If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, then multiplication gives an area for the rectangle of 5.6088 square meters.
代表著符合任何符號我通通都要。

那如果我想找空白字元呢?
首先釐清一下哪些是屬於空白字元, 例如斷行(/n)、Tab(/t)、換頁(/f)...等等。
這些都會讓你的畫面產生不可見的字元,
以下符號也都會讓你看到空白字元:
 \n、\t、\f、\r、\x0B
所以我們如果想找空白字元, 就可以利用[\n\t\f\r\x0B]這樣的表示式來表示。

但是這邊出現了一個重點,
在Java當中, \代表跳脫字元, 所以當我們要顯示跳脫字元, 就必須在多加一個跳脫字元,
也就是\\ , 所以當我們要找出空白字元的時候,
表示式就必須是這樣[\\n\\t\\f\\r\\x0B],
String htmlCode = 
   "If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, " +
   "then multiplication gives an area for the rectangle of 5.6088 square meters.";
Pattern pattern = Pattern.compile("[\\n\\t\\f\\r\\x0B]");
Matcher matcher = pattern.matcher(htmlCode);
while(matcher.find()) {
    System.out.print(matcher.group());
}
因此, 印出來的結果就是空白, 你可以數看看有幾個空白(咦?),
不過很麻煩的是, 每次我們要找出空白, 就要打這麼一大串,
真是有夠浪費時間的,
所以正規表示又很聰明的, 將找空白的符號濃縮成\s,
這樣一來, 我們只需要輸入\\s就可以讓正規表示知道要找的是空白符號了。

那還有沒有其他的濃縮符號, 當然有!

\\d : 找出數字0-9, 相當於[0-9]
String htmlCode = 
   "If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, " +
   "then multiplication gives an area for the rectangle of 5.6088 square meters.";
Pattern pattern = Pattern.compile("\\d");
Matcher matcher = pattern.matcher(htmlCode);
while(matcher.find()) {
    System.out.print(matcher.group());
}
輸出結果12345656088

\\D : 找出除了數字以外的集合
String htmlCode = 
   "If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, " +
   "then multiplication gives an area for the rectangle of 5.6088 square meters.";
Pattern pattern = Pattern.compile("\\D");
Matcher matcher = pattern.matcher(htmlCode);
while(matcher.find()) {
    System.out.print(matcher.group());
}
輸出結果
If the sides of a rectangle are measured as . meters and . meters, then multiplication gives an area for the rectangle of . square meters.

\\s : 找出空白的字元
String htmlCode = 
   "If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, " +
   "then multiplication gives an area for the rectangle of 5.6088 square meters.";
Pattern pattern = Pattern.compile("\\s");
Matcher matcher = pattern.matcher(htmlCode);
while(matcher.find()) {
    System.out.print(matcher.group());
}
輸出結果空白

\\S : 找出非會產生空白的字元,除了\\s以外的集合
String htmlCode = 
   "If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, " +
   "then multiplication gives an area for the rectangle of 5.6088 square meters.";
Pattern pattern = Pattern.compile("\\S");
Matcher matcher = pattern.matcher(htmlCode);
while(matcher.find()) {
    System.out.print(matcher.group());
}
輸出結果
Ifthesidesofarectanglearemeasuredas1.23metersand4.56meters,thenmultiplicationgivesanareafortherectangleof5.6088squaremeters.

\\w : 找出a-z A-Z 0-9_,英文大小寫數字和底線, 相當於[a-zA-Z0-9_]
String htmlCode = 
   "If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, " +
   "then multiplication gives an area for the rectangle of 5.6088 square meters.";
Pattern pattern = Pattern.compile("\\w");
Matcher matcher = pattern.matcher(htmlCode);
while(matcher.find()) {
    System.out.print(matcher.group());
}
輸出結果Ifthesidesofarectanglearemeasuredas123metersand456metersthenmultiplicationgivesanareafortherectangleof56088squaremeters

\\W : 找出非文字, 除了\\w以外的集合
String htmlCode = 
   "If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, " +
   "then multiplication gives an area for the rectangle of 5.6088 square meters.";
Pattern pattern = Pattern.compile("\\W");
Matcher matcher = pattern.matcher(htmlCode);
while(matcher.find()) {
    System.out.print(matcher.group());
}
輸出結果
         .   . ,          .  .
把所有的空白和標點符號都找出來了。


如果你想要找尋某一個單字, 你只需要輸入該單字, 例如你想要找meters這個字,
String htmlCode = 
   "If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, " +
   "then multiplication gives an area for the rectangle of 5.6088 square meters.";
Pattern pattern = Pattern.compile("meters");
Matcher matcher = pattern.matcher(htmlCode);
while(matcher.find()) {
    System.out.print(matcher.group());
}
輸出結果metersmetersmeters
你就可以看到找出三個meters


^符號
寫在表示式的第一個位置時候,表示符號後面的第一個符號必須出現在字串開頭的位置。
String htmlCode = 
   "If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, " +
   "then multiplication gives an area for the rectangle of 5.6088 square meters.";
Pattern pattern = Pattern.compile("^I");
Matcher matcher = pattern.matcher(htmlCode);
while(matcher.find()) {
    System.out.print(matcher.group());
}
印出結果是I


^如果寫在[]的表示式裡面如果是第一個字元就代表反向,如果不是則當成一般字元。
String htmlCode = 
   "If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, " +
   "then multiplication gives an area for the rectangle of 5.6088 square meters.";
Pattern pattern = Pattern.compile("[^h]");
Matcher matcher = pattern.matcher(htmlCode);
while(matcher.find()) {
    System.out.print(matcher.group());
}
印出結果是
If te sides of a rectangle are measured as 1.23 meters and 4.56 meters, ten multiplication gives an area for te rectangle of 5.6088 square meters.
[h]的意思就是找出h, [^h]的意思就是排除h, 因此h都不見了。


$符號
寫在表示式最後一個位置時候, 表示前一個的符號必須出現在字串尾端的位置。
String htmlCode = 
   "If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, " +
   "then multiplication gives an area for the rectangle of 5.6088 square meters.";
Pattern pattern = Pattern.compile(".$");
Matcher matcher = pattern.matcher(htmlCode);
while(matcher.find()) {
    System.out.print(matcher.group());
}
由於字串最後一個字為. ,所以.$將會把.印出來, 結果是. 。
$如果寫在表示式中間的時候沒什麼特別的意義。


()符號
如果把一堆字元放進左右括弧符號內, 就會形成一個群組,
搜尋的時候, 會按照群組的排列大小寫順序來尋找。
String htmlCode = 
   "If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, " +
   "then multiplication gives an area for the rectangle of 5.6088 square meters.";
Pattern pattern = Pattern.compile("(sides)");
Matcher matcher = pattern.matcher(htmlCode);
while(matcher.find()) {
    System.out.print(matcher.group());
}
結果會印出sides
那如果把s跟e的位置對調, 變成找尋sidse, 就會找不到任何東西。
String htmlCode = 
   "If the sides of a rectangle are measured as 1.23 meters and 4.56 meters, " +
   "then multiplication gives an area for the rectangle of 5.6088 square meters.";
Pattern pattern = Pattern.compile("(sidse)");
Matcher matcher = pattern.matcher(htmlCode);
while(matcher.find()) {
    System.out.print(matcher.group());
}
結果沒印出任何東西

那你會說我不用括弧表示不也一樣?
是沒錯, 但是括弧在後面有很重要的應用, 之後會介紹。