正則表達式查詢

1 在C#中使用.NET通常表達式引擎

  下面將經過一個樣例的開發,執行並顯示一些搜索的結果,說明通常表達式的一些特性,以及如何在C#中使用.NET通常表達式引擎。說明使用字符串時應在前面加上符號@。html

String Text=@"I can not find my position in Beijing";

把這個文本稱爲輸入字符串,爲了說明通常表達式.NET類,本文先進行一次純文本的搜索,此次搜索不帶任何轉義序列或通常表達式命令。假定要查找全部字符串ion,把這個搜索字符串稱爲模式。使用通常表達式和上面聲明的變量Text,編寫出下面的代碼:正則表達式

String Pattern = "ion";
MatchCollection Matches = Regex.Matches(Text,Pattern,RegexOptions);
foreach(Match NextMatch in Matches)
{ Console.WriteLine(NextMatch.Index); }

在這段代碼中,使用了System.Text.RegularExpressions名稱空間中Regex類的靜態方法Match()。這個方法的參數是一些輸入文本、一個模式和RegexOptions每句中的一組可選標誌。Matches()返回MatchCollection,每一個匹配都用一個Match對象來表示。在上面的代碼中,只是在集合中迭代,使用Match類的Index屬性,返回輸入文本中匹配所在的索引。運行這段代碼,將獲得1個匹配項。

  通常集合的功能主要取決於模式字符串。緣由是模式字符串不只僅包含純文本。如前所述。還包含元字符和轉義序列,元字符是給出命令的特殊字符,而轉義序列的工做方式與C#的轉義序列相同,它們都是以反斜槓\開頭的字符,具備特殊的含義。例如,假定要查找以n開頭的字,就可使用轉義序列\b,它表示一個字的邊界(字的邊界是以某個字母數字標的字符開頭,或者後面是一個空白字符或標點符號),下面編寫以下代碼:函數

String Pattern = @"\bn";
MatchCollection Matches = Regex.Matches(Text,Pattern,RegexOptions.IgnoreCase|
RegexOptions.ExplicitCapture);

要在運行時把\b傳遞給.NET通常表達式引擎,反斜槓\不該被C#編譯器解釋爲轉義序列。若是要查找以序列ion結尾的字,可使用下面的代碼:spa

String Pattern = @"ion\b";

若是要查找以字母n開頭,以序列ion結尾的全部字,須要一個以\bn開頭,以ion\b結尾的模式,中間內容怎麼辦?須要告訴計算機n和ion中間的內容能夠是任意長度的字符,只要字符不是空白便可,正確的模式以下所示:code

String Pattern = @"\bn\S*ion\b";

 

2  特定字符或轉義序列
  大多數重要的正則表達式語言運算符都是非轉義的單個字符。轉義符 \(單個反斜槓)通知正則表達式分析器反斜槓後面的字符不是運算符。例如,分析器將星號 (*) 視爲重複限定符,而將後跟星號的反斜槓 (\*) 視爲 Unicode 字符 002A。
  使用通常表達式要習慣的一點是,查看像這樣怪異的字符序列,但這個序列的工做是很是邏輯化的。轉義序列\S表示任何不適空白的字符。*稱爲數量詞,其含義是前面的字符能夠重複任意次,包括0次。序列\S*表示任何不適空白的字符。所以,上面的模式匹配於以n開頭,以ion結尾的任何單個字。下表中列出的字符轉義在正則表達式和替換模式中都會被識別。
  表1:特定字符或轉義序列htm

特定字符或轉義序列 含義 樣例 匹配的樣例
^ 輸入文本的開頭 ^B B,但只能是文本中的第一個字符
$ 輸入文本的結尾 X$ X,但只能是文本中的最後一個字符
. 除了換行字符(\n)之外的全部單個字符 i.ation isation、ization
* 能夠重複0次或屢次的前導字符 ra*t rat、raat等
+ 能夠重複1次或屢次的前導字符 ra+t rt、rat、raat等
能夠重複0次或1次的前導字符 ra?t 只有rt和rat匹配
\s 任何空白字符 \sa [space]a,\ta,\na(\t和\n與C#的\t和\n含義相同)
\S 任何不是空白的字符 \SF aF,rF,cF,但不能是\tf
\b 字邊界 ion\b 以ion結尾的任何字
\B 不是字邊界的位置 \BX\B 字中間的任何X

  若是要搜索一個元字符,也能夠經過帶有反斜槓的轉義字符來表示。例如,.表示除了換行字符之外的任何字符,而\.表示一個點。 能夠把可替換的字符放在方括號中,請求匹配包含這些字符。例如,[1|c]表示字符能夠是1或者是c。若是要搜索map或者man,可使用序列"ma[n|p]"(僅指引號內字符,下面雷同)。在方括號中,也能夠制定一個範圍,例如"[a-z]"表示全部的小寫字母(使用連字號 (-) 容許指定連續字符範圍),"[B-F]"表示B到F之間的全部大寫字母,"[0-9]"表示一個數字,若是要搜索一個整數(該序列只包含0到9的字符),就能夠編寫"[0-9]+"(注意,使用+字符表示至少要有這樣一個數字,但能夠有多個數字,因此九、83和3443等都是匹配的。) 下面看看通常表達式的結果,編寫一個實例RegularExpressionsZzy。創建幾個通常表達式,顯示其結果,讓用戶瞭解一下表達式是如何工做的。
  該實例的核心是一個方法WriteMatches(),它把MatchCollection中的全部匹配以比較詳細的方式顯示出來。對於每一個匹配,它都會顯示該匹配在輸入字符串中所在的索引,匹配的字符串和一個略長的字符串,其中包含輸入文本中至多8個外圍字符,其中至少有5個字符放在匹配的前面,至多5個字符放在匹配的後面(若是匹配的位置在輸入文本的開頭或結尾5個字符內,則結果中匹配先後的字符就會少於4個)。換言之,靠近輸入文本末尾的匹配應是"and messaging ofd",匹配的先後各有5個字符,但位於輸入文本的最後一個字上的匹配就應是"g of data",匹配的字後只有一個字符。由於在該字符的後面是字符串的結尾。這個長字符串能夠更清楚地代表通常表達式是在什麼地方查找到匹配的:對象

static void WriteMatches(string text, MatchCollection matches)
{
 Console.WriteLine("Original text was: \n\n" + text + "\n");
 Console.WriteLine("No. of matches: " + matches.Count);
 foreach (Match nextMatch in matches)
 {
  int Index = nextMatch.Index;
  string result = nextMatch.ToString();
  int charsBefore = (Index < 5) ? Index : 5;
  int fromEnd = text.Length - Index - result.Length;
  int charsAfter = (fromEnd < 5) ? fromEnd : 5;
  int charsToDisplay = charsBefore + charsAfter + result.Length;
  Console.WriteLine("Index: {0}, \tString: {1}, \t{2}",Index, result, 
  text.Substring(Index - charsBefore, charsToDisplay));
 }
}

在這個方法中,處理過程是肯定在較長的字符串中有多少個字符能夠顯示,而無需超限輸入文本的開頭或結尾。注意在Match對象上使用了另外一個屬性Value,它包含標識該匹配的字符串,並且,RegularExpressionsZzy只包含名爲Find_po,Find_n等的方法,這些方法根據本文執行某些搜索操做。
  blog

3 正則表達式選項
  可使用影響匹配行爲的選項修改正則表達式模式。能夠經過兩種基本方法設置正則表達式選項:其一是能夠在 Regex(pattern, options) 構造函數中的 options 參數中指定,其中 options 是 RegexOptions 枚舉值的按位"或"組合;其二是使用內聯 (?imnsx-imnsx:) 分組構造或 (?imnsx-imnsx) 其餘構造在正則表達式模式內設置它們。
  在內聯選項構造中,一個選項或一組選項前面的減號 (-) 用於關閉這些選項。例如,內聯構造 (?ix-ms) 將打開 IgnoreCase 和 IgnorePatternWhiteSpace 選項而關閉 Multiline 和 Singleline 選項。
  表2:RegexOptions 枚舉的成員以及等效的內聯選項字符索引

RegexOption 成員 內聯字符 說明
None 指定不設置任何選項。
IgnoreCase i 指定不區分大小寫的匹配。
Multiline m 指定多行模式。更改 ^ 和 $ 的含義,以使它們分別與任何行的開頭和結尾匹配,而不僅是與整個字符串的開頭和結尾匹配。
ExplicitCapture n 指定惟一有效的捕獲是顯式命名或編號的 (?<name>...) 形式的組。這容許圓括號充當非捕獲組,從而避免了由 (?:...) 致使的語法上的笨拙。
Compiled 指定正則表達式將被編譯爲程序集。生成該正則表達式的 Microsoft 中間語言 (MSIL) 代碼;以較長的啓動時間爲代價,獲得更快的執行速度。
Singleline s 指定單行模式。更改句點字符 (.) 的含義,以使它與每一個字符(而不是除 \n 外的全部字符)匹配。
IgnorePatternWhitespace x 指定從模式中排除非轉義空白並啓用數字符號 (#) 後面的註釋。請注意,空白永遠不會從字符類中消除。
RightToLeft 指定搜索是從右向左而不是從左向右進行的。具備此選項的正則表達式將移動到起始位置的左邊而不是右邊。(所以,起始位置應指定爲字符串的結尾而不是開頭。)爲了不構造具備無限循環的正則表達式的可能性,此選項不能在中流指定。可是,(?<) 回顧後發構造提供了可用做子表達式的相似替代物。
ECMAScript 指定已爲表達式啓用了符合 ECMAScript 的行爲。此選項僅可與 IgnoreCase 和 Multiline 標誌一塊兒使用。將 ECMAScript 同任何其餘標誌一塊兒使用將致使異常。