當前位置:成語大全網 - 書法字典 - 什麽是“正則表達式”?

什麽是“正則表達式”?

如果您曾經使用過Perl或任何其他內置正則表達式支持的語言,您壹定知道用正則表達式處理文本和匹配模式是多麽容易。如果您不熟悉這個術語,那麽“正則表達式”就是壹個字符串,它定義了搜索匹配字符串的模式。

許多語言,包括Perl、PHP、Python、JavaScript和JScript,都支持使用正則表達式來處理文本,壹些文本編輯器使用正則表達式來實現高級的“搜索-替換”功能。那麽Java呢?在撰寫本文時,壹個包含使用正則表達式進行文本處理的Java規範請求已經被認可,您可以期待在下壹版本的JDK中看到它。

但是,如果現在需要使用正則表達式呢?妳可以從Apache.org下載開源的雅加達-ORO圖書館。本文接下來的內容簡單介紹正則表達式的基礎知識,然後以雅加達-ORO API為例介紹如何使用正則表達式。

壹、正則表達式的基礎知識

先說簡單的。假設您要搜索包含字符“cat”的字符串,用於搜索的正則表達式是“cat”。如果搜索不區分大小寫,單詞“catalog”、“Catherine”和“Sophie”都可以匹配。也就是說:

1.1周期符號

假設妳在玩英文拼字遊戲,想要找到三個字母的單詞,而這些單詞必須以字母“T”開頭,以字母“N”結尾。另外,假設有壹本英語詞典,妳可以用正則表達式搜索它的所有內容。要構建這個正則表達式,可以使用通配符——句點符號“.”。這樣,完整的表達就是“t.n”,匹配“tan”、“ten”、“tin”、“ton”,也匹配“t#n”、“tpn”甚至“t n”,以及其他許多無意義的組合。這是因為句點符號匹配所有字符,包括空格、制表符甚至換行符:

1.2方括號符號

為了解決句點符號匹配範圍過寬的問題,可以在方括號(“[]”)中指定有意義的字符。此時,只有方括號中指定的字符參與匹配。即正則表達式“t[aeio]n”只匹配“tan”、“Ten”、“tin”、“ton”。但是“Toon”不匹配,因為只能匹配方括號內的單個字符:

1.3或符號

如果除了上面匹配的所有單詞之外,還想匹配“toon”,可以使用“|”運算符。運算符的基本含義是or運算。要匹配“toon”,使用正則表達式“t(a|e|i|o|oo)n”。這裏不能用方展開符號,因為方括號只允許匹配單個字符;此處必須使用括號“()”。圓括號也可以用於分組,如後面所述。

1.4表示匹配數的符號。

表1顯示了代表匹配數的符號,這些符號用於確定緊挨著符號左側的符號的出現次數:

假設我們想在壹個文本文件中搜索美國社會保險號。這個號碼的格式是999-99-9999。用於匹配它的正則表達式如圖1所示。在正則表達式中,連字符(“-”)有特殊的含義。它代表壹個範圍,例如從0到9。因此,在匹配社會安全號中的連字符時,應該在其前面添加壹個轉義字符“\”。

圖1:以123-12-1234的形式匹配所有社保號碼。

假設在搜索時,您希望連字符出現或不出現——也就是說,999-99-9999和9999999的格式是正確的。這時候可以加上“?”在連字符後面。數量限制符號,如圖2所示:

圖2:以123-12-1234和121234的形式匹配所有社保號。

讓我們看另壹個例子。美國汽車牌照的壹種格式是四個數字加兩個字母。它的正則表達式前面是數字部分“[0-9]{4}”和字母部分“[A-Z]{2}”。圖3顯示了完整的正則表達式。

圖3:匹配典型的美國汽車車牌號,比如8836KV。

1.5無符號

“”符號被稱為“否”符號。如果用在方括號中,“”表示不想匹配的字符。例如,圖4中的正則表達式匹配除了以字母“X”開頭的單詞之外的所有單詞。

圖4:匹配除了以“X”開頭的單詞之外的所有單詞

1.6括號和空白符號

假設從生日日期中提取月份部分,格式為“June 26,1951”,用來匹配這個日期的正則表達式可以如圖5所示:

圖5:匹配所有月DD、YYYY格式的日期。

新符號\s \是壹個空白符號,它匹配所有空白字符,包括制表符。如果字符串匹配正確,接下來如何提取月份部分?只需在月份周圍添加壹個括號來創建壹個組,然後使用ORO API(將在本文後面詳細討論)來提取它的值。修改後的正則表達式如圖6所示:

圖6:以月DD,YYYY格式匹配所有日期,並將月值定義為第壹組。

1.7其他符號

為簡單起見,您可以使用壹些為常見正則表達式創建的快捷符號。如表2所示:

表2:常見符號

例如,在前面的社會安全號碼示例中,只要出現“[0-9]”,我們就可以使用“\d”。修改後的正則表達式如圖7所示:

圖7:匹配123-12-1234格式的所有社保號碼。

第二,雅加達-ORO圖書館

Java程序員可以使用許多開源的正則表達式庫,其中許多支持Perl 5兼容的正則表達式語法。我在這裏選擇了雅加達-ORO正則表達式庫,這是最全面的正則表達式API之壹,它與Perl 5正則表達式完全兼容。此外,它也是優化最好的API之壹。

雅加達-ORO圖書館曾被稱為OROMatcher,Daniel Savarese慷慨地將其捐贈給了雅加達項目。您可以根據本文末尾參考資料中的說明下載它。

我將首先簡要介紹使用雅加達-ORO庫時必須創建和訪問的對象,然後介紹如何使用雅加達-ORO API。

▲pattern compler對象

首先,創建perl 5編譯器類的壹個實例,並將其分配給PatternCompiler接口對象。Perl5Compiler是PatternCompiler接口的壹個實現,它允許您將正則表達式編譯成用於匹配的模式對象。

▲圖案對象

要將正則表達式編譯成模式對象,調用編譯器對象的compile()方法,並在call參數中指定正則表達式。例如,您可以編譯正則表達式“t[aeio]n ”,如下所示:

默認情況下,編譯器創建區分大小寫的模式。所以上面的代碼編譯出來的模式只匹配“tin”、“tan”、“ten”、“ton”,不匹配“Tin”、“taN”。要創建不區分大小寫的模式,您應該在調用編譯器時指定壹個額外的參數:

創建模式對象後,可以通過PatternMatcher類將它用於模式匹配。

▲ PatternMatcher對象

PatternMatcher對象基於模式對象和字符串執行匹配檢查。您實例化壹個Perl5Matcher類,並將結果分配給PatternMatcher接口。Perl 5Matcher類是PatternMatcher接口的實現,它根據Perl5正則表達式語法執行模式匹配:

使用PatternMatcher對象,可以使用多種方法進行匹配操作。這些方法的第壹個參數是需要根據正則表達式進行匹配的字符串:

布爾匹配(字符串輸入,模式模式):當輸入字符串和正則表達式需要精確匹配時使用。換句話說,正則表達式必須完整地描述輸入字符串。

布爾匹配前綴(字符串輸入,模式模式):當正則表達式匹配輸入字符串的開頭時使用。

Boolean contains (string input,pattern pattern):當正則表達式要匹配輸入字符串的壹部分(即必須是子字符串)時使用。

此外,在上述三個方法調用中,還可以使用PatternMatcherInput對象代替String對象作為參數;此時,您可以從字符串中的最後壹個匹配位置繼續匹配。當壹個字符串可能有多個子字符串匹配給定的正則表達式時,使用PatternMatcherInput對象作為參數是很有用的。當用PatternMatcherInput對象作為參數替換String時,上述三種方法的語法如下:

布爾匹配(模式匹配輸入,模式模式)

布爾matchesPrefix(模式匹配輸入,模式模式)

布爾包含(模式匹配輸入,模式模式)

三、應用實例

讓我們看壹些雅加達-ORO圖書館的應用例子。

3.1日誌文件處理

任務:分析Web服務器日誌文件,以確定每個用戶在網站上花費的時間。在典型的BEA WebLogic日誌文件中,日誌記錄的格式如下:

分析這個日誌記錄,可以發現從這個日誌文件中可以提取出兩個東西:IP地址和頁面訪問時間。您可以使用分組符號(括號)從日誌記錄中提取IP地址和時間戳。

首先,我們來看看IP地址。IP地址由4個字節組成,每個字節的值在0到255之間,每個字節用句點分隔。因此,IP地址中的每個字節至少有壹位,最多三位。圖8顯示了為IP地址編寫的正則表達式:

圖8:匹配IP地址

IP地址中的句點字符必須轉義(前面加“\”),因為IP地址中的句點有其原始含義,而不是正則表達式語法中的特殊含義。正則表達式中句點的特殊含義在本文前面已經介紹過了。

日誌記錄的時間部分用壹對方括號括起來。可以如下提取方括號中的所有內容:首先搜索起始方括號字符("["),提取不超過結束方括號字符("]")的所有內容,向前查找,直到找到結束方括號字符。圖9顯示了這部分的正則表達式。

圖9:至少匹配壹個字符,直到找到“]”

現在,用分組符號(括號)將上面兩個正則表達式組合成壹個表達式,這樣就可以從日誌記錄中提取IP地址和時間。註意,為了匹配“-”(但不是提取),“\s-\s-\s”加在正則表達式中間。完整的正則表達式如圖10所示。

圖10:匹配IP地址和時間戳

既然已經編寫了正則表達式,就可以編寫使用正則表達式庫的Java代碼了。

要使用雅加達-ORO庫,首先創建壹個正則表達式字符串和壹個要分析的日誌字符串:

這裏使用的正則表達式幾乎與圖10中的正則表達式完全相同,只有壹個例外:在Java中,必須對每個正斜杠(\ ")進行轉義。圖10不是Java的代表,所以我們應該在每個前面加壹個“以避免編譯錯誤”。