茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1669421 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
LSxMF_00014.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

爪哇咖啡屋 : [分享]正則運算式

發表者 討論內容
冷日
(冷日)
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)
--------------------------------------------------------------------------------
冷日
(冷日)
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-9]+3704
有小數點的實數[0-9]+\.[0-9]+7.93
英文詞彙[A-Za-z]+Code
變數名稱[A-Za-z_][A-Za-z0-9_]*_counter
Email[a-zA-Z0-9_]+@[a-zA-Z0-9\._]+ wt.ude.timk|ccc#wt.ude.timk|ccc
URL http://[a-zA-Z0-9\./_]+ http://ccc.kmit.edu.tw/mybook/

為了協助讀者理解這些範例,我們有必要對範例中的一些正則表達式符號進行說明。

在實數的範例中,使用 \. 代表小數點符號 .,不熟悉正則表達式的讀者一定覺得奇怪,為何要加上斜線符號 \ 呢?這是因為在正則表達式當中,有許多符號具有特殊意義,例如點符號 . 是用來表示任意字元的,星號 * 是代表 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 - 陳鍾誠的網站
冷日
(冷日)
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 | 就是愛程式
前一個主題 | 下一個主題 | 頁首 | | |



Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|