|
發表者 |
討論內容 |
冷日 (冷日) |
發表時間:2008/3/18 4:19 |
- Webmaster
- 註冊日: 2008/2/19
- 來自:
- 發表數: 15771
|
- [分享]正則運算式
- [轉貼]正則運算式 [精華]
-------------------------------------------------------------------------------- 第一部分: ----------------- 正則運算式(REs)通常被錯誤地認?是只有少數人理解的一種神秘語言。在表面上它們確實看起來雜亂無章,如果你不知道它的語法,那?它的代碼在你眼?只是一堆文字垃圾而已。實際上,正則運算式是非常簡單並且可以被理解。讀完這篇文章後,你將會通曉正則運算式的通用語法。 支援多種平臺 正則運算式最早是由數學家Stephen Kleene于1956年提出,他是在對自然語言的遞增研究成果的基礎上提出來的。具有完整語法的正則運算式使用在字元的格式比對方面上,後來被應用到資訊技術領域。自從那時起,正則運算式經過幾個時期的發展,現在的標準已經被ISO(國際標準組織)批准和被Open Group組織認定。 正則運算式並非一門專用語言,但它可用於在一個文件或字元?查找和替代文本的一種標準。它具有兩種標準:基本的正則運算式(BRE),擴展的正則運算式(ERE)。ERE包括BRE功能和另外其他的概念。 許多程式中都使用了正則運算式,包括xsh,egrep,sed,vi以及在UNIX平臺下的程式。它們可以被很多語言採納,如HTML和XML,這些採納通常只是整個標準的一個子集。 比你想象的還要普通 隨著正則運算式移植到交叉平臺的程式語言的發展,這的功能也日益完整,使用也逐漸廣泛。網路上的搜索引擎使用它,e-mail程式也使用它,即使你不是一個UNIX程式師,你也可以使用規則語言來簡化你的程式而縮短你的開發時間。 正則運算式101 很多正則運算式的語法看起來很相似,這是因?你以前你沒有研究過它們。通配符是RE的一個結構類型,即重復操作。讓我們先看一看ERE標準的最通用的基本語法類型。?了能夠提供具有特定用途的範例,我將使用幾個不同的程式。 第二部分: ---------------------- 字元比對 正則運算式的關鍵之處在於確定你要搜索比對的東西,如果沒有這一概念,Res將毫無用處。 每一個運算式都包含需要查找的指令,如表A所示。 Table A: Character-matching regular expressions 格式說明: --------------- 操作: 解釋: 例子: 結果: ---------------- . Match any one character grep .ord sample.txt Will match “ford”, “lord”, “2ord”, etc. in the file sample.txt. ----------------- [ ] Match any one character listed between the brackets grep [cng]ord sample.txt Will match only “cord”, “nord”, and “gord” --------------------- [^ ] Match any one character not listed between the brackets grep [^cn]ord sample.txt Will match “lord”, “2ord”, etc. but not “cord” or “nord” grep [a-zA-Z]ord sample.txt Will match “aord”, “bord”, “Aord”, “Bord”, etc. grep [^0-9]ord sample.txt Will match “Aord”, “aord”, etc. but not “2ord”, etc. 重復操作符 重復操作符,或數量詞,都描述了查找一個特定字元的次數。它們常被用於字元比對語法以查找多行的字元,可參見表B。 Table B: Regular expression repetition operators 格式說明: --------------- 操作: 解釋: 例子: 結果: ---------------- ? Match any character one time, if it exists egrep “?erd” sample.txt Will match “berd”, “herd”, etc. and “erd” ------------------ * Match declared element multiple times, if it exists egrep “n.*rd” sample.txt Will match “nerd”, “nrd”, “neard”, etc. ------------------- + Match declared element one or more times egrep “[n]+erd” sample.txt Will match “nerd”, “nnerd”, etc., but not “erd” -------------------- {n} Match declared element exactly n times egrep “[a-z]{2}erd” sample.txt Will match “cherd”, “blerd”, etc. but not “nerd”, “erd”, “buzzerd”, etc. ------------------------ {n,} Match declared element at least n times egrep “.{2,}erd” sample.txt Will match “cherd” and “buzzerd”, but not “nerd” ------------------------ {n,N} Match declared element at least n times, but not more than N times egrep “n[e]{1,2}rd” sample.txt Will match “nerd” and “neerd” 第三部分: ---------------- 錨 錨是指它所要比對的格式,如圖C所示。使用它能方便你查找通用字元的合併。例如,我用vi行編輯器命令:s來代表substitute,這一命令的基本語法是: s/pattern_to_match/pattern_to_substitute/ Table C: Regular expression anchors ------------- 操作 解釋 例子 結果 --------------- ^ Match at the beginning of a line s/^/blah / Inserts “blah “ at the beginning of the line --------------- $ Match at the end of a line s/$/ blah/ Inserts “ blah” at the end of the line --------------- \< Match at the beginning of a word s/\</blah/ Inserts “blah” at the beginning of the word egrep “\<blah” sample.txt Matches “blahfield”, etc. ------------------ \> Match at the end of a word s/\>/blah/ Inserts “blah” at the end of the word egrep “\>blah” sample.txt Matches “soupblah”, etc. --------------- \b Match at the beginning or end of a word egrep “\bblah” sample.txt Matches “blahcake” and “countblah” ----------------- \B Match in the middle of a word egrep “\Bblah” sample.txt Matches “sublahper”, etc. 間隔 Res中的另一可便之處是間隔(或插入)符號。實際上,這一符號相當於一個OR語句並代表|符號。下面的語句返回文件sample.txt中的“nerd” 和 “merd”的控制碼: egrep “(n|m)erd” sample.txt 間隔功能非常強大,特別是當你尋找文件不同拼寫的時候,但你可以在下面的例子得到相同的結果: egrep “[nm]erd” sample.txt 當你使用間隔功能與Res的高級特性連接在一起時,它的真正用處更能體現出來。 第四部分: ---------------- 一些保留字元 Res的最後一個最重要特性是保留字元(也稱特定字元)。例如,如果你想要查找“ne*rd”和“ni*rd”的字元,格式比對語句“n[ei]*rd”與“neeeeerd” 和 “nieieierd”相符合,但並不是你要查找的字元。因?‘*’(星號)是個保留字元,你必須用一個反斜線符號來替代它,即:“n[ei]\*rd”。其他的保留字元包括: ^ (carat) . (period) [ (left bracket) $ (dollar sign) ( (left parenthesis) ) (right parenthesis) | (pipe) * (asterisk) + (plus symbol) ? (question mark) { (left curly bracket, or left brace) \ backslash 一旦你把以上這些字元包括在你的字元搜索中,毫無疑問Res變得非常的難讀。比如說以下的PHP中的eregi搜索引擎代碼就很難讀了。 eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*$",$sendto) 你可以看到,程式的意圖很難把握。但如果你?開保留字元,你常常會錯誤地理解代碼的意思。 總結 在本文中,我們揭開了正則運算式的神秘面紗,並列出了ERE標準的通用語法。如果你想閱覽Open Group組織的規則的完整描述,你可以參見:Regular Expressions,歡迎你在其中的討論區發表你的問題或觀點。
---------------------------------------- 正則運算式和Java編程語言 ----------------------------------------- 類和方法 下面的類根據正則運算式指定的模式,與字元序列進行比對。 Pattern 類別 Pattern類別的實例表示以字串形式指定的正則運算式,其語法類似於Perl所用的語法。 用字串形式指定的正則運算式,必須先編譯成Pattern類的 實例。生成的模式用於創建Matcher物件,它根據正則運算式與任 意字元序列進行比對。多個比對器可以共用一個模式,因?它是非專屬的。 用compile方法把給定的正則運算式編譯成模式,然後用 matcher方法創建一個比對器,這個比對器將根據此模式對給定輸 入進行比對。pattern 方法可返回編譯這個模式所用的正則表達 式。 split方法是一種方便的方法,它在與此模式比對的位置將給 定輸入序列切分開。下面的例子演示了:
/** 用 split 以 逗號 和 空格 分隔的輸入字串進行切割*/
import java.util.regex.*;
public class Splitter {
public static void main(String[] args) throws Exception {
Pattern p = Pattern.compile("[,/\\s]+");
String [] result = p.split("one,two, three four , five/six");
for (int i = 0; i < result.length; i++) { System.out.println(result[i]); }
}
}
Matcher 類別 Matcher類別的實例用於根據給定的字串序列模式,對字元序 列進行比對。使用CharSequence介面把輸入提供給比對器,以便 支援來自多種多樣輸入源的字元的比對。 通過調用某個模式的matcher方法,從這個模式生成比對器。 比對器創建之後,就可以用它來執行三類不同的比對操作: matches方法試圖根據此模式,對整個輸入序列進行比對。 lookingAt方法試圖根據此模式,從開始處對輸入序列進 行比對。 find方法將掃描輸入序列,尋找下一個與模式比對的地方。 這些方法都會返回一個表示成功或失敗的布林值。如果比對成功,通過查詢 比對器的狀態,可以獲得更多的資訊 這個類還定義了用新字串替換比對序列的方法,這些字串的內容如果需 要的話,可以從比對結果推算得出。 appendReplacement方法先添加字串中從當前位置到下一個 比對位置之間的所有字元,然後添加替換值。appendTail添加的 是字串中從最後一次比對的位置之後開始,直到結尾的部分。 例如,在字串blahcatblahcatblah中,第一個 appendReplacement添加blahdog。第二個 appendReplacement添加blahdog,然後 appendTail添加blah,就生成了: blahdogblahdogblah。請參見示例簡單的單詞替換。 CharSequence介面 CharSequence介面?許多不同類型的字元序列提供了統一的只 讀訪問。你提供要從不同來源搜索的資料。用String, StringBuffer 和CharBuffer實現CharSequence,,這樣就可以很容易地從它們那獲得要搜索的資料。如果這些可用資料源沒一個合適的,你可以通過實現CharSequence介面,編寫你自己的輸入源。 Regex情景範例 以下代碼範例演示了java.util.regex套裝軟體在各種常見情形 下的用法: 簡單的單詞替換
public class Replacement {
public static void main(String[] args) {
// Create a pattern to match cat
Pattern p = Pattern.compile("cat");
// Create a matcher with an input string
Matcher m = p.matcher("one cat," + " two cats in the yard");
StringBuffer sb = new StringBuffer();
boolean b = m.find();
// Loop through and create a new String with the replacements
while ( b ) {
m.appendReplacement(sb,"dog");
b = m.find();
}
// Add the last segment of input to the new String
m.appendTail(sb);
System.out.println(sb.toString());
}
}
電子郵件確認 以下代碼是這樣一個例子:你可以檢查一些字元是不是一個電子郵件位址。 它並不是一個完整的、適用於所有可能情形的電子郵件確認程式,但是可以在 需要時加上它。
/** Checks for invalid characters* in email addresses*/
public class EmailValidation {public static void main(String[] args) throws Exception {
String input = "@sun.com";
//Checks for email addresses starting with
//inappropriate symbols like dots or @ signs.
Pattern p = Pattern.compile("^\\.|^\\@");
Matcher m = p.matcher(input);
if (m.find())System.err.println("Email addresses don't start" + " with dots or @ signs.");
//Checks for email addresses that start with
//www. and prints a message if it does.
p = Pattern.compile("^www\\.");
m = p.matcher(input);
if (m.find()) {System.out.println("Email addresses don't start" + " with \"www.\", only web pages do.");}
p = Pattern.compile("[^A-Za-z0-9\\.\\@_\\-~#]+");
m = p.matcher(input);
StringBuffer sb = new StringBuffer();
boolean result = m.find();
boolean deletedIllegalChars = false;
while(result) {
deletedIllegalChars = true;
m.appendReplacement(sb, "");
result = m.find();
}
// Add the last segment of input to the new
Stringm.appendTail(sb);
input = sb.toString();
if (deletedIllegalChars) {System.out.println("It contained incorrect characters" + " , such as spaces or commas.");}
}
}
從文件中刪除控制字元
/* This class removes control characters from a named* file.*/
import java.util.regex.*;
import java.io.*;
public class Control {
public static void main(String[] args) throws Exception {
//Create a file object with the file name
//in the argument:File
fin = new File("fileName1");
File fout = new File("fileName2");
//Open and input and output
streamFileInputStream fis = new FileInputStream(fin);
FileOutputStream fos = new FileOutputStream(fout);
BufferedReader in = new BufferedReader( new InputStreamReader(fis));
BufferedWriter out = new BufferedWriter( new OutputStreamWriter(fos));
// The pattern matches control
charactersPattern p = Pattern.compile("{cntrl}");
Matcher m = p.matcher("");
String aLine = null;
while((aLine = in.readLine()) != null) {
m.reset(aLine);
//Replaces control characters with an empty
//string.
String result = m.replaceAll("");
out.write(result);
out.newLine();
}
in.close();
out.close();
}
}
文件查找
/** Prints out the comments found in a .java file.*/
import java.util.regex.*;
import java.io.*;
import java.nio.*;
import java.nio.charset.*;
import java.nio.channels.*;
public class CharBufferExample {
public static void main(String[] args) throws Exception {
// Create a pattern to match
commentsPattern p = Pattern.compile("//.*$", Pattern.MULTILINE);
// Get a Channel for the source
fileFile f = new File("Replacement.java");
FileInputStream fis = new FileInputStream(f);
FileChannel fc = fis.getChannel();
// Get a CharBuffer from the source
fileByteBuffer bb = fc.map(FileChannel.MAP_RO, 0, (int)fc.size());
Charset cs = Charset.forName("8859_1");
CharsetDecoder cd = cs.newDecoder();
CharBuffer cb = cd.decode(bb);
// Run some
matchesMatcher m = p.matcher(cb);
while (m.find())System.out.println("Found comment: "+m.group());
}
}
結論 現在Java編程語言中的模式比對和許多其他編程語言一樣靈活了。可以在應 用程式中使用正則運算式,確保資料在輸入資料庫或發送給應用程式其他部分之 前,格式是正確的,正則運算式還可以用於各種各樣的管理性工作。簡而言之, 在Java編程中,可以在任何需要模式比對的地方使用正則運算式。
-------------------------------------------------------------------------------- [轉貼] JDK1.4之正規表示式 written by william chen(06/19/2002) -------------------------------------------------------------------------------- 什麼是正規表示式呢(Reqular Expressions) 就是針對檔案、字串,透過一種很特別的表示式來作search與replace。因為在unix上有很多系統設定都是存放在文字檔中,因此網管或程式設計常常需要作搜尋與取代,所以發展出一種特殊的命令叫做正規表示式。 我們可以很簡單的用 "s/</lt;/g" 這個正規式將字串中所有含有"<"的字元轉換成"lt;",因此jdk1.4提供了一組正規表示式的package供大家使用,若是jdk1.4以下的可以到http://jakarta.apache.org/oro取得相關功能的package。 剛剛列出的一串符號" s/</lt;/g" 就是正規語法,所以請先瞭解正規的表示式 適用於j2sdk1.4的正規語法 "." 代表任何字元 正規式 原字串 符合之字串 . ab a .. abc ab "+" 代表一個或以個以上的字元 "*" 代表零個或是零個以上的字元 正規式 原字串 符合之字串 + ab ab * abc abc "( )"群組 正規式 原字串 符合之字串 (ab)* aabab abab 字元類 正規式 原字串 符合之字串 [a-dA-D0-9]* abczA0 abcA0 [^a-d]* abe0 e0 [a-d]* abcdefgh abab 簡式 \d 等於 [0-9] 數字 \D 等於 [^0-9] 非數字 \s 等於 [ \t\n\x0B\f\r] 空白字元 \S 等於 [^ \t\n\x0B\f\r] 非空白字元 \w 等於 [a-zA-Z_0-9] 數字或是英文字 \W 等於 [^a-zA-Z_0-9] 非數字與英文字 每一行的開頭或結尾 ^ 表示每行的開頭 $ 表示每行的結尾 -------------------------------------------------------------------------------- 正規表示式 java.util.regex 相關的類別 Pattern—正規表示式的類別 Matcher—經過正規化的結果 PatternSyntaxExpression—Exception thrown while attempting to compile a regular expression 範例1: 將字串中所有符合"<"的字元取代成"lt;" import java.io.*; import java.util.regex.*; /** * 將字串中所有符合"<"的字元取代成"lt;" */ public static void replace01(){ // BufferedReader lets us read line-by-line Reader r = new InputStreamReader( System.in ); BufferedReader br = new BufferedReader( r ); Pattern pattern = Pattern.compile( "<" ); // 搜尋某字串所有符合'<'的字元 try{ while (true) { String line = br.readLine(); // Null line means input is exhausted if (line==null) break; Matcher a = pattern.matcher(line); while(a.find()){ System.out.println("搜尋到的字元是" + a.group()); } System.out.println(a.replaceAll("lt;"));// 將所有符合字元取代成lt; } }catch(Exception ex){ex.printStackTrace();}; } 範例2: import java.io.*; import java.util.regex.*; /** * 類似StringTokenizer的功能 * 將字串以","分隔然後比對哪個token最長 */ public static void search01(){ // BufferedReader lets us read line-by-line Reader r = new InputStreamReader( System.in ); BufferedReader br = new BufferedReader( r ); Pattern pattern = Pattern.compile( ",\\s*" );// 搜尋某字串所有","的字元 try{ while (true) { String line = br.readLine(); String words[] = pattern.split(line); // Null line means input is exhausted if (line==null) break; // -1 means we haven't found a word yet int longest=-1; int longestLength=0; for (int i=0; i<words.length; ++i) { System.out.println("分段:" + words[i] ); if (words[i].length() > longestLength) { longest = i; longestLength = words[i].length(); } } System.out.println( "長度最長為:" + words[longest] ); } }catch(Exception ex){ex.printStackTrace();}; } -------------------------------------------------------------------------------- 其他的正規語法 /^\s* # 忽略每行開始的空白字元 (M(s|r|rs)\.) # 符合 Ms., Mrs., and Mr. (titles) --------------------------------------------------------------------------------
|
|
冷日 (冷日) |
發表時間:2016/5/26 2:23 |
- Webmaster
- 註冊日: 2008/2/19
- 來自:
- 發表數: 15771
|
- [分享]正規表示式 Regular Expression
正規表示式 Regular Expression 簡介正規語法 (Regular Grammar) 是一種相當簡單的語法,這種語法被 Perl 語言成功的用於字串比對,接著成為重要的程式設計工具。此種標準的正規語法後來被稱為正則表達式 (Regular Expression)。目前,大部分的語言都已納入正則表達式的函式庫,正則表達是可以說是程式設計師必定要瞭解的工具,也就是常識的一部分。系統程式設計師更應該要瞭解正則表達式,因為正規語法是程式語言當中,用來描述基本詞彙 (Vocabulary),並據以建構詞彙掃描器 (Lexer) 的基礎語法,Lexer 是編譯器的基本元件之一。 假如我們要用正則表達式描述整數數字,那麼,可以用 [0123456789]+ 這個表達式,其中的中括號 [ 與 ] 會框住一群字元,用來代表字元群,加號 + 所代表的是重複 1 次或以上,因此,該表達式就可以描述像 3702451 這樣的數字。然而,在正則表達式中,為了更方便撰寫,於是允許用 [0-9]+ 這樣的式子表達同樣的概念,其中的 0-9 其實就代表了 0123456789 等字元,這是一種簡便的縮寫法。甚至,可以再度縮短後以 [\d]+ 代表,其中的 \d 就代表數字所成的字元集合。 利用範例學習是理解正則表達式的有效方法,表格 1 就顯示了一些具有代表性的正則表達式範例。 表格 1. 正則表達式的範例 為了協助讀者理解這些範例,我們有必要對範例中的一些正則表達式符號進行說明。 在實數的範例中,使用 \. 代表小數點符號 .,不熟悉正則表達式的讀者一定覺得奇怪,為何要加上斜線符號 \ 呢?這是因為在正則表達式當中,有許多符號具有特殊意義,例如點符號 . 是用來表示任意字元的,星號 * 是代表 0 次或以上,加號 + 代表一次或以上,在正則表達式當中,有許多這類的特殊字元,因此用斜線 \ 代表跳出字元,就像 C 語言當中 printf 函數內的用途一樣。因此,當我們看到 \ 符號時,必須繼續向後看,才能知道其所代表的意義。表格 2 列出了正則表達式當中大部份的重要符號之意義,以供讀者參考。 表格 2. 正則表達式當中的符號之意義 字元 | 描述 | \ | 將下一個字元標記為一個特殊字元、或一個原義字元、或一個向後引用、或一個八進制轉義符。例如,“n”匹配字元“n”。“\n”匹 配一個分行符號。序列“\\”匹配“\”而“\(”則匹配“(”。 | ^ | 匹配輸入字串的開始位置。如果設置了RegExp物件的Multiline屬性,^也匹配“\n”或“\r”之後的位置。 | $ | 匹配輸入字串的結束位置。如果設置了RegExp物件的Multiline屬性,$也匹配“\n”或“\r”之前的位置。 |
* | 匹配前面的子運算式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等價於{0,}。 | + | 匹配前面的子運算式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等價於{1,}。 | ? | 匹配前面的子運算式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等價於{0,1}。 | {n} | n是一個非負整數。匹配確定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的兩個o。 | {n,} | n是一個非負整數。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等價於“o+”。“o{0,}”則等價於“o*”。 | {n,m} | m和n均為非負整數,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”將匹配“fooooood”中的前三個o。“o{0,1}”等價於“o?”。請注意在逗號和兩個數之間不能有空格。 | ? | 當該字元緊跟在任何一個其他限制符(*,+,?,{n},{n,},{n,m})後面時,匹配模式是非貪婪的。非貪婪模式盡可能少的匹配所搜索的字串,而預設的貪婪模式則盡可能多的匹配所搜索的字串。例如,對於字串“oooo”,“o+?”將匹配單個“o”,而“o+”將匹配所有“o”。 | . | 匹配除“\n”之外的任何單個字元。要匹配包括“\n”在內的任何字元,請使用像“[.\n]”的模式。 | (pattern) | 匹配pattern並獲取這一匹配。所獲取的匹配可以從產生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中則使用$0…$9屬性。要匹配圓括號字元,請使用“\(”或“\)”。 |
(?:pattern) | 匹配pattern但不獲取匹配結果,也就是說這是一個非獲取匹配,不進行存儲供以後使用。這在使用“或”字元(|)來組合一個模式的各個部分是很有用。例如,“industr(?:y|ies)就是一個比”industry|industries'更簡略的運算式。 | (?=pattern) | 正向預查,在任何匹配pattern的字串開始處匹配查找字串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。例 如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配 “Windows3.1”中的“Windows”。預查不消耗字元,也就是說,在一個匹配發生後,在最後一次匹配之後立即開始下一次匹配的搜索,而不是從 包含預查的字元之後開始。 | (?!pattern) | 負向預查,在任何不匹配pattern的字串開始處匹配查找字串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。例如 “Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中 的“Windows”。預查不消耗字元,也就是說,在一個匹配發生後,在最後一次匹配之後立即開始下一次匹配的搜索,而不是從包含預查的字元之後開始 | x|y | 匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”則匹配“zood”或“food”。 | [xyz] | 字元集合。匹配所包含的任意一個字元。例如,“[abc]”可以匹配“plain”中的“a”。 | [^xyz] | 負值字元集合。匹配未包含的任意字元。例如,“[^abc]”可以匹配“plain”中的“p”。 | [a-z] | 字元範圍。匹配指定範圍內的任意字元。例如,“[a-z]”可以匹配“a”到“z”範圍內的任意小寫字母字元。 |
[^a-z] | 負值字元範圍。匹配任何不在指定範圍內的任意字元。例如,“[^a-z]”可以匹配任何不在“a”到“z”範圍內的任意字元。 | \b | \B | 匹配非單詞邊界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。 | \cx | 匹配由x指明的控制字元。例如,\cM匹配一個Control-M或回車符。x的值必須為A-Z或a-z之一。否則,將c視為一個原義的“c”字元。 | \d | 匹配一個數位字元。等價於[0-9]。 | \D | 匹配一個非數位字元。等價於[^0-9]。 | \f | 匹配一個換頁符。等價於\x0c和\cL。 | \n | 匹配一個分行符號。等價於\x0a和\cJ。 | \r | 匹配一個回車符。等價於\x0d和\cM。 | \s | 匹配任何空白字元,包括空格、定位字元、換頁符等等。等價於[\f\n\r\t\v]。 | \S | 匹配任何非空白字元。等價於[^\f\n\r\t\v]。 | \t | 匹配一個定位字元。等價於\x09和\cI。 | \v | 匹配一個垂直定位字元。等價於\x0b和\cK。 | \w | 匹配包括底線的任何單詞字元。等價於“[A-Za-z0-9_]”。 | \W | 匹配任何非單詞字元。等價於“[^A-Za-z0-9_]”。 | \xn | 匹配n,其中n為十六進位轉義值。十六進位轉義值必須為確定的兩個數位長。例如,“\x41”匹配“A”。“\x041”則等價於“\x04”&“1”。規則運算式中可以使用ASCII編碼。 |
\num | 匹配num,其中num是一個正整數。對所獲取的匹配的引用。例如,“(.)\1”匹配兩個連續的相同字元。 | \n | 標識一個八進制轉義值或一個向後引用。如果\n之前至少n個獲取的子運算式,則n為向後引用。否則,如果n為八進位數字(0-7),則n為一個八進制轉義值。 | \nm | 標識一個八進制轉義值或一個向後引用。如果\nm之前至少有nm個獲得子運算式,則nm為向後引用。如果\nm之前至少有n個獲取,則n為一個後跟文字m的向後引用。如果前面的條件都不滿足,若n和m均為八進位數字(0-7),則\nm將匹配八進制轉義值nm。 | \nml | 如果n為八進位數字(0-3),且m和l均為八進位數字(0-7),則匹配八進制轉義值nml。 | \un | 匹配n,其中n是一個用四個十六進位數位表示的Unicode字元。例如,\u00A9匹配版權符號(©)。 |
正則表達式在許多語言當中 (像是 Java, C#, Ruby, Python 等) 都已經有支援良好的函式庫,然而,在標準 C 語言的函式庫當中卻沒有這方面的函數,因此,我們使用 C# 這個語言說明正則表達式的用法。 範例 1. 在 C# 語言當中使用正則表達式進行樣式抽取的程式範例
using System; using System.Collections.Generic; using System.Text.RegularExpressions; public class Regexp { // 測試主程式 static void Main(string[] args) { List<String> list = Regexp.matches(@" 32.4 + 56.7 is 89.1 ", @"[0-9]+\.[0-9]+", 0); foreach (String token in list) Console.WriteLine(token); } // 傳回text 中符合正規表示式pattern 的所有段落。 public static List<String> matches(String text, String pattern, int groupId) { List<String> rzList = new List<String>(); Match match = Regex.Match(text, pattern); for (int i = 0; match.Success; i++) { rzList.Add(match.Groups[groupId].Value); match = match.NextMatch(); } return rzList; } }
執行結果
D:\ExampleCode>csc Regexp.cs Microsoft (R) Visual C# 2008 Compiler version 3.5.21022.8 for Microsoft (R) .NET Framework version 3.5 Copyright (C) Microsoft Corporation. All rights reserved. D:\ExampleCode>Regexp 32.4 56.7 89.1
參考文獻資料來源:張智星的網站 - 正規表示式
正規表示式 說明及範例 比對不成立之字串 /a/ 含字母 “a” 的字串,例如 “ab”, “bac”, “cba” “xyz” /a./ 含字母 “a” 以及其後任一個字元的字串,例如 “ab”, “bac”(若要比對.,請使用 \.) “a”, “ba” /^xy/ 以 “xy” 開始的字串,例如 “xyz”, “xyab”(若要比對 ^,請使用 \^) “axy”, “bxy” /xy$/ 以 “xy” 結尾的字串,例如 “axy”, “abxy”以 “xy” 結尾的字串,例如 “axy”, “abxy” (若要比對 $,請使用 \$) “xya”, “xyb” [13579] 包含 “1〃 或 “3〃 或 “5〃 或 “7〃 或 “9〃 的字串,例如:”a3b”, “1xy” “y2k” [0-9] 含數字之字串 不含數字之字串 [a-z0-9] 含數字或小寫字母之字串 不含數字及小寫字母之字串 [a-zA-Z0-9] 含數字或字母之字串 不含數字及字母之字串 b[aeiou]t “bat”, “bet”, “bit”, “bot”, “but” “bxt”, “bzt” [^0-9] 不含數字之字串(若要比對 ^,請使用 \^) 含數字之字串 [^aeiouAEIOU] 不含母音之字串(若要比對 ^,請使用 \^) 含母音之字串 [^\^] 不含 “^” 之字串,例如 “xyz”, “abc” “xy^”, “a^bc” . 正規表示式的特定字元 說明 等效的正規表示式 \d 數字 [0-9] \D 非數字 [^0-9] \w 數字、字母、底線 [a-zA-Z0-9_] \W 非 \w [^a-zA-Z0-9_] \s 空白字元 [ \r\t\n\f] \S 非空白字元 [^ \r\t\n\f] . 正規表示式 說明 /a?/ 零或一個 a(若要比對? 字元,請使用 \?) /a+/ 一或多個 a(若要比對+ 字元,請使用 \+) /a*/ 零或多個 a(若要比對* 字元,請使用 \*) /a{4}/ 四個 a /a{5,10}/ 五至十個 a /a{5,}/ 至少五個 a /a{,3}/ 至多三個 a /a.{5}b/ a 和 b中間夾五個(非換行)字元 . 字元 說明 簡單範例 \ 避開特殊字元 /A\*/ 可用於比對 “A*”,其中 * 是一個特殊字元,為避開其特殊意義,所以必須加上 “\” ^ 比對輸入列的啟始位置 /^A/ 可比對 “Abcd” 中的 “A”,但不可比對 “aAb” $ 比對輸入列的結束位置 /A$/ 可比對 “bcdA” 中的 “A”,但不可比對 “aAb” * 比對前一個字元零次或更多次 /bo*/ 可比對 “Good boook” 中的 “booo”,亦可比對 “Good bk” 中的 “b” + 比對前一個字元一次或更多次,等效於 {1,} /a+/ 可比對 “caaandy” 中的 “aaa”,但不可比對 “cndy” ? 比對前一個字元零次或一次 /e?l/ 可比對 “angel” 中的 “el”,也可以比對 “angle” 中的 “l” . 比對任何一個字元(但換行符號不算) /.n/ 可比對 “nay, an apple is on the tree” 中的 “an” 和 “on”,但不可比對 “nay” (x) 比對 x 並將符合的部分存入一個變數 /(a*) and (b*)/ 可比對 “aaa and bb” 中的 “aaa” 和 “bb”,並將這兩個比對得到的字串設定至變數 RegExp.$1 和 RegExp.$2。 xy 比對 x 或 y /a*b*/g 可比對 “aaa and bb” 中的 “aaa” 和 “bb” {n} 比對前一個字元 n 次,n 為一個正整數 /a{3}/ 可比對 “lllaaalaa” 其中的 “aaa”,但不可比對 “aa” {n,} 比對前一個字元至少 n 次,n 為一個正整數 /a{3,}/ 可比對 “aa aaa aaaa” 其中的 “aaa” 及 “aaaa”,但不可比對 “aa” {n,m} 比對前一個字元至少 n 次,至多 m 次,m、n 均為正整數 /a{3,4}/ 可比對 “aa aaa aaaa aaaaa” 其中的 “aaa” 及 “aaaa”,但不可比對 “aa” 及 “aaaaa” [xyz] 比對中括弧內的任一個字元 /[ecm]/ 可比對 “welcome” 中的 “e” 或 “c” 或 “m” [^xyz] 比對不在中括弧內出現的任一個字元 /[^ecm]/ 可比對 “welcome” 中的 “w”、”l”、”o”,可見出其與 [xyz] 功能相反。(同時請注意 /^/ 與 [^] 之間功能的不同。) [\b] 比對退位字元(Backspace character) 可以比對一個 backspace ,也請注意 [\b] 與 \b 之間的差別 \b 比對英文字的邊界,例如空格 例如 /\bn\w/ 可以比對 “noonday” 中的 ‘no’ ; /\wy\b/ 可比對 “possibly yesterday.” 中的 ‘ly’ \B 比對非「英文字的邊界」 例如, /\w\Bn/ 可以比對 “noonday” 中的 ‘on’ , 另外 /y\B\w/ 可以比對 “possibly yesterday.” 中的 ‘ye’ \cX 比對控制字元(Control character),其中 X 是一個控制字元 /\cM/ 可以比對 一個字串中的 control-M \d 比對任一個數字,等效於 [0-9] /[\d]/ 可比對 由 “0〃 至 “9〃 的任一數字 但其餘如字母等就不可比對 \D 比對任一個非數字,等效於 [^0-9] /[\D]/ 可比對 “w” “a”⋯ 但不可比對如 “7〃 “1〃 等數字 \f 比對 form-feed 若是在文字中有發生 “換頁” 的行為 則可以比對成功 \n 比對換行符號 若是在文字中有發生 “換行” 的行為 則可以比對成功 \r 比對 carriage return \s 比對任一個空白字元(White space character),等效於 [ \f\n\r\t\v] /\s\w*/ 可比對 “A b” 中的 “b” \S 比對任一個非空白字元,等效於 [^ \f\n\r\t\v] /\S/\w* 可比對 “A b” 中的 “A” \t 比對定位字元(Tab) \v 比對垂直定位字元(Vertical tab) \w 比對數字字母字元(Alphanumerical characters)或底線字母(”_”),等效於 [A-Za-z0-9_] /\w/ 可比對 “.A _!9〃 中的 “A”、”_”、”9〃。 \W 比對非「數字字母字元或底線字母」,等效於 [^A-Za-z0-9_] /\W/ 可比對 “.A _!9〃 中的 “.”、” “、”!”,可見其功能與 /\w/ 恰好相反。 \ooctal 比對八進位,其中octal是八進位數目 /\oocetal123/ 可比對 與 八進位的ASCII中 “123〃 所相對應的字元值。 \xhex 比對十六進位,其中hex是十六進位數目 /\xhex38/ 可比對 與 16進位的ASCII中 “38〃 所相對應的字元。
原文出處:正規表示式 Regular Expression - 陳鍾誠的網站
|
|
|
冷日 (冷日) |
發表時間:2016/5/26 2:28 |
- Webmaster
- 註冊日: 2008/2/19
- 來自:
- 發表數: 15771
|
- [分享]正規表示式 Regular Expression
正規表示式 Regular Expression本人,實在對正規表示式沒輒,前幾天跑去天瓏,居然還看到一本歐萊禮出的「精通正規表示式」(本人的膚淺譯名),真是傻眼,不過因為已經被另外一本將近一千八百元的原文書弄到心裡淌血,否則,大概也會衝動之下把他買下來吧!(雖然就算買到了也不見得有用…XD) Anyway,還是把一些資料給放在這裡,免得臨時要找找不到。 資料來源: 張智星的網站 – 正規表示式 正規表示式 | 說明及範例 | 比對不成立之字串 | /a/ | 含字母 “a” 的字串,例如 “ab”, “bac”, “cba” | “xyz” | /a./ |
含字母 “a” 以及其後任一個字元的字串,例如 “ab”, “bac”(若要比對.,請使用 \.) | “a”, “ba” | /^xy/ | 以 “xy” 開始的字串,例如 “xyz”, “xyab”(若要比對 ^,請使用 \^) | “axy”, “bxy” | /xy$/ | 以 “xy” 結尾的字串,例如 “axy”, “abxy”以 “xy” 結尾的字串,例如 “axy”, “abxy” (若要比對 $,請使用 \$) | “xya”, “xyb” | [13579] | 包含 “1” 或 “3” 或 “5” 或 “7” 或 “9” 的字串,例如:”a3b”, “1xy” | “y2k” | [0-9] | 含數字之字串 | 不含數字之字串 | [a-z0-9] | 含數字或小寫字母之字串 | 不含數字及小寫字母之字串 | [a-zA-Z0-9] | 含數字或字母之字串 | 不含數字及字母之字串 |
b[aeiou]t | “bat”, “bet”, “bit”, “bot”, “but” | “bxt”, “bzt” | [^0-9] | 不含數字之字串(若要比對 ^,請使用 \^) | 含數字之字串 | [^aeiouAEIOU] | 不含母音之字串(若要比對 ^,請使用 \^) | 含母音之字串 | [^\^] | 不含 “^” 之字串,例如 “xyz”, “abc” | “xy^”, “a^bc” |
. 正規表示式的特定字元 | 說明 | 等效的正規表示式 | \d | 數字 | [0-9] | \D | 非數字 | [^0-9] | \w | 數字、字母、底線 | [a-zA-Z0-9_] | \W | 非 \w | [^a-zA-Z0-9_] | \s | 空白字元 | [ \r\t\n\f] | \S | 非空白字元 | [^ \r\t\n\f] |
. 正規表示式 | 說明 | /a?/ | 零或一個 a(若要比對? 字元,請使用 \?) |
/a+/ | 一或多個 a(若要比對+ 字元,請使用 \+) | /a*/ | 零或多個 a(若要比對* 字元,請使用 \*) | /a{4}/ | 四個 a | /a{5,10}/ | 五至十個 a | /a{5,}/ | 至少五個 a | /a{,3}/ | 至多三個 a | /a.{5}b/ | a 和 b中間夾五個(非換行)字元 |
. 字元 | 說明 | 簡單範例 | \ | 避開特殊字元 | /A\*/ 可用於比對 “A*”,其中 * 是一個特殊字元,為避開其特殊意義,所以必須加上 “\” | ^ | 比對輸入列的啟始位置 | /^A/ 可比對 “Abcd” 中的 “A”,但不可比對 “aAb” | $ | 比對輸入列的結束位置 | /A$/ 可比對 “bcdA” 中的 “A”,但不可比對 “aAb” | * | 比對前一個字元零次或更多次 | /bo*/ 可比對 “Good boook” 中的 “booo”,亦可比對 “Good bk” 中的 “b” |
+ | 比對前一個字元一次或更多次,等效於 {1,} | /a+/ 可比對 “caaandy” 中的 “aaa”,但不可比對 “cndy” | ? | 比對前一個字元零次或一次 | /e?l/ 可比對 “angel” 中的 “el”,也可以比對 “angle” 中的 “l” | . | 比對任何一個字元(但換行符號不算) | /.n/ 可比對 “nay, an apple is on the tree” 中的 “an” 和 “on”,但不可比對 “nay” | (x) | 比對 x 並將符合的部分存入一個變數 | /(a*) and (b*)/ 可比對 “aaa and bb” 中的 “aaa” 和 “bb”,並將這兩個比對得到的字串設定至變數 RegExp.$1 和 RegExp.$2。 | xy | 比對 x 或 y | /a*b*/g 可比對 “aaa and bb” 中的 “aaa” 和 “bb” | {n} | 比對前一個字元 n 次,n 為一個正整數 | /a{3}/ 可比對 “lllaaalaa” 其中的 “aaa”,但不可比對 “aa” |
{n,} | 比對前一個字元至少 n 次,n 為一個正整數 | /a{3,}/ 可比對 “aa aaa aaaa” 其中的 “aaa” 及 “aaaa”,但不可比對 “aa” | {n,m} | 比對前一個字元至少 n 次,至多 m 次,m、n 均為正整數 | /a{3,4}/ 可比對 “aa aaa aaaa aaaaa” 其中的 “aaa” 及 “aaaa”,但不可比對 “aa” 及 “aaaaa” | [xyz] | 比對中括弧內的任一個字元 | /[ecm]/ 可比對 “welcome” 中的 “e” 或 “c” 或 “m” | [^xyz] | 比對不在中括弧內出現的任一個字元 | /[^ecm]/ 可比對 “welcome” 中的 “w”、”l”、”o”,可見出其與 [xyz] 功能相反。(同時請注意 /^/ 與 [^] 之間功能的不同。) | [\b] | 比對退位字元(Backspace character) | 可以比對一個 backspace ,也請注意 [\b] 與 \b 之間的差別 | \b | 比對英文字的邊界,例如空格 | 例如 /\bn\w/ 可以比對 “noonday” 中的 ‘no’ ; /\wy\b/ 可比對 “possibly yesterday.” 中的 ‘ly’ |
\B | 比對非「英文字的邊界」 | 例如, /\w\Bn/ 可以比對 “noonday” 中的 ‘on’ , 另外 /y\B\w/ 可以比對 “possibly yesterday.” 中的 ‘ye’ | \cX | 比對控制字元(Control character),其中 X 是一個控制字元 | /\cM/ 可以比對 一個字串中的 control-M | \d | 比對任一個數字,等效於 [0-9] | /[\d]/ 可比對 由 “0” 至 “9” 的任一數字 但其餘如字母等就不可比對 | \D | 比對任一個非數字,等效於 [^0-9] | /[\D]/ 可比對 “w” “a”… 但不可比對如 “7” “1” 等數字 | \f | 比對 form-feed | 若是在文字中有發生 “換頁” 的行為 則可以比對成功 | \n | 比對換行符號 | 若是在文字中有發生 “換行” 的行為 則可以比對成功 | \r | 比對 carriage return | | \s | 比對任一個空白字元(White space character),等效於 [ \f\n\r\t\v] | /\s\w*/ 可比對 “A b” 中的 “b” |
\S | 比對任一個非空白字元,等效於 [^ \f\n\r\t\v] | /\S/\w* 可比對 “A b” 中的 “A” | \t | 比對定位字元(Tab) | | \v | 比對垂直定位字元(Vertical tab) | | \w | 比對數字字母字元(Alphanumerical characters)或底線字母(”_”),等效於 [A-Za-z0-9_] | /\w/ 可比對 “.A _!9” 中的 “A”、”_”、”9″。 | \W | 比對非「數字字母字元或底線字母」,等效於 [^A-Za-z0-9_] | /\W/ 可比對 “.A _!9” 中的 “.”、” “、”!”,可見其功能與 /\w/ 恰好相反。 | \o octal | 比對八進位,其中 octal 是八進位數目 | /\oocetal123/ 可比對 與 八進位的ASCII中 “123” 所相對應的字元值。 | \x hex | 比對十六進位,其中 hex 是十六進位數目 | /\xhex38/ 可比對 與 16進位的ASCII中 “38” 所相對應的字元。 |
原文出處:正規表示式 Regular Expression | 就是愛程式
|
|
|