讀古今文學網 > 精通正則表達式(第3版) > 使用.NET正則表達式 >

使用.NET正則表達式

Using.NET Regular Expressions

.NET正則表達式功能強大,語法清晰,通過完整而易於使用的類接口來操作。雖然微軟的正則表達式包做得很漂亮,文檔卻相反——它非常糟糕。文檔不夠全面,編寫不夠清晰,缺乏組織,有時甚至不能保證正確性。我花了很長的時間才整理清楚,所以希望這一章的內容能夠讓讀者更清楚地理解.NET的正則表達式。

正則表達式快速入門

Regex Quickstart

即使不需要知道正則類模型(regex class model)的細節,也可以直接上手使用.NET的正則表達式包。理解細節能夠讓我們獲得更多的信息,提高工作效率,但是下面這些簡單的例子沒有明確創建任何正則類,細節將在例子之後提到。

使用正則表達式庫的程序必須在文件的開頭寫上下面這條語句,下面的例子假設此句已經存在:

Imports System.Text.RegularExpressions

下面的例子都能正常處理String變量TestStr。本章的所有例子中,選用的變量名都以斜體標注。

快速入門:在字符串中尋找匹配

這段程序檢查一個正則表達式是否能匹配字符串:

這個例子使用了匹配模式:

快速入門:匹配,獲得匹配文本

這個例子顯示正則表達式實際匹配的文本。如果沒有匹配,TheNum就是空字符串。

這個例子使用了一個匹配模式:

快速入門:匹配,獲得捕獲文本

這段程序以字符串的形式返回第1個捕獲分組的匹配文本:

請注意,在C#中應使用Groups[1]取代Groups(1)。

下面的程序目的相同,只是使用了match選項:

仍然是相同的程序,只是使用命名捕獲:

快速入門:查找和替換

這個例子把輸入的字符串轉換為 HTML「安全」的字符,把特殊的 HTML 轉換為 HTML entity:

replacement字符串(第3個參數)的處理是很特殊的,第424頁的補充內容做了講解。例如,在 replacement 字符串中,『$&』會被正則表達式真正匹配的文本所替代,下面的例子給大寫的單詞添加<B>…</B>:

這個例子把<B>…</B>(使用不區分大小寫的匹配)替換為<I>…</I>:

包概覽

Package Overview

通過豐富而便捷的類結構,可以使用.NET正則表達式幾乎所有的功能。下面這個完整的控制台程序,提供了關於整個包的概覽,它明確使用各種對像來進行簡單的匹配。

通過命令行提示符來執行,把「d+w+」應用到同樣的文本,結果是:

matched [1st] from char#12 for 3 chars.

導入正則表達式名字空間

你注意到程序頭部的 Imports System.Text.RegularExpressions 了嗎?任何用到.NET正則對象的VB程序都必須寫上這一條語句,才能通過編譯。

C#中對應的是:

using System.Text.RegularExpressions;//C#中應這麼寫

這個例子說明了基本的正則對象的用法,下面兩行主要行為:

也可以合併為一行:

Dim M as Match=Regex.Match(SampleText,〞d+w+〞)\'對字符串應用pattern

合併的寫法更容易使用,程序員需要輸入的代碼更少,需要記錄的對象也更少。不過,它的效率會稍微低一些(☞432)。在下面幾頁中,我們首先會看到原始的對象,然後學習「便捷」函數,例如靜態函數Regex.Match,以及合適的使用時機。

為簡便起見,在程序片段的例子中,我會省略下面這幾行:

本書的第96、99、204、219和237頁出現過VB的例子,回顧它們也許有所幫助。

核心對像概覽

Core Object Overview

在深入細節之前,先來看看.NET的正則對像模型。對像模型是一套類結構,正則表達式的各種功能通過它們來提供。.NET的正則功能通過7個高度交互的類來提供,實際上你可能只需要理解其中3個——也就是下一頁的圖9-1所示的3個類——即可,它們展示了對『May· 16,·1998』重複應用「s+(d+)」的過程。

Regex對像

第一步是創建Regex對象,例如:

Dim R as Regex=New Regex(〞s+(d+)〞)

在這裡,我們用一個Regex對像表示「s+(d+)」,將其保存在變量R中。獲得Regex對像之後,我們可以通過Match(text)方法將其應用到一段文本,返回與第一次匹配結果相關的信息:

Dim M as Match=R.Match(〞May 16,1998〞)

圖9-1:.NET正則表達式相關對像模型

Match對像

Regex對象的Match(…)方法通過創建並返回Match對像來提供匹配信息。Match對像有多個屬性,包括Success(一個表示匹配是否成功的Boolean值)和Value(如果匹配成功,則保存實際匹配文本的副本)。稍後我們會看到Match的所有屬性的列表。

Match對像返回的細節中還包括捕獲型括號所匹配的文本。前面Perl的例子使用$1保存第一組捕獲型括號匹配的文本。.NET提供了兩種辦法:如果要取得純文本,可以按照索引值訪問Match對象的Groups屬性,例如Groups(1).Value,它等價於Perl的$1(請注意,C#中使用的是Groups[1].Value)。另一個辦法是使用Result方法,請參考第429頁。

Group對像

前一段中的Groups(1)其實是對Group對象的引用,後面的.Value引用它的Value屬性(也就是此分組對應的文本)。每一組捕獲型括號都對應一個Group對象,另外還有一個「虛擬分組(virtual group)」,其編號為0,它保存全局匹配的信息。

因此,MatchObj.Value 和 MatchObj.Groups(0).Value 是等價的——都是全局匹配的文本的副本。第一種寫法更加簡潔方便,但我們必須知道存在編號為0的分組,因為MatchObj.Groups.Count(也就是Match關聯的分組的數目)包含了它。如果「s+(d+)」能夠匹配成功,MatchObj.Groups.Count的值就是2(標號為0的全局匹配和$1)。

Capture對像

Capture對象的使用並不頻繁,請參考第437頁的介紹。

匹配時會計算出所有結果

把正則表達式應用到字符串中,得到一個 Match對象,此時所有的結果(匹配的位置,每個捕獲分組匹配的內容等)都會計算出來,封裝到Match對像中。訪問Match對象的屬性和方法,包括它的Group對像(及其屬性和方法)只是取回已經計算好的結果。