?
快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

?和記娛h188下載app:磨練構建正則表達式模式的技能

?

經由過程本文的進修,您可以增添一些有用的設計實際正則表達式 (regexp) 的技能。構建正則表達式是任何治理員日常事情中的一部分。為了構造返回所需前提的成功正則表達式,必要進修以模式匹配的角度進行思慮,而這種技能必要花大年夜量的光陰進行演習。

小序

UNIX® 治理員天天都必要構建和應用正則表達式 (regexp) 進行文本模式匹配。大年夜多半說話都支持正則表達式的某種實現。有的利用法度榜樣(如 EMACS)具有正則表達式搜索功能,并且您可以經由過程各類敕令行對象應用正則表達式。無論什么利用法度榜樣,構建精確的正則表達式的關鍵之處在于,識別僅滿意必要匹配的數據的模式,以便在輸入中掃除其他不需要的內容。

出于這個目的,本文將慢慢先容幾種正則表達式模式構建技術,并先容它們若何贊助您完成各類老例義務。

應用正則表達式 (regexp)

除非分外闡明,否則本文中應用的示例都是擴展可移植操作系統接口(擴展 POSIX)的正則表達式。假如經由過程敕令行(如應用 egrep 實用對象)應用它們,您應該根據必要引用各類正則表達式。請記著,不合的正則表達式實現之間存在一些差別,您可能不得不適應所應用的特定的對象、利用法度榜樣或說話中的詳細實現。

匹配整行內容

^ 元字符匹配行首,而 $ 匹配行尾,假如將它們組?和記娛h188下載app合在一路(如 ^$),它們將匹配空行。(這個表達式的鏡像,即 $^,是弗成能匹配成功的,它將永世 都無法匹配到有效行。)這個基礎的正則表達式是許多繁雜正則表達式的根基,假如您還不習氣應用這個基礎的正則表達式,那么您應該慢慢養成應用它的習氣。應用它來構建匹配整行內容 的模式。

在用戶字典文件 (/usr/dict/words) 中搜索是一個很好的基礎模式。(有些版本的 UNIX 將用戶字典放在 /usr/share/dict/words 中。)

例如,假設您忘懷了若何拼寫單詞 fuchsia。此中是否包孕 sh 或 cs 呢?您所知道的只是,它以 fu 開首并以 ia 結尾。

考試測驗應用這個模式進行搜索:

$ egrep -i '^fu.*ia$' /usr/dict/words

-i 標志表示在搜索歷程中不區分大年夜小寫。在這個示例中,由于 fuchsia 拼寫精確,以是在返回的單詞中包括這個單詞。

根據長度匹配行

應用大年夜括號元字符 ({ }) 指定前面的正則表達式匹配若干次,如表 1 所示。當您將它們添加到剛才先容的整行搜索中時,您可以指定行的長度。

表 1. 大年夜括號元字符的含義

示例描述

{X}

這個字符對前面的正則表達式匹配 X 次。

{X,}

這個字符對前面的正則表達式匹配 X 或更多 次。

{X,Y}

這個字符對前面的正則表達式匹配至少 X 而不跨越 Y 次。

并不是所有擴展正則表達式的實現都支持大年夜括號。此外,根據詳細的實現,您可能必要先應用反斜杠對其進行轉義。

您可以應用這個正則表達式獲得字典中以單詞長度為順序的申報。所得到結果的數目取決于本地系統的字典文件中單詞的數目,然而,它應該與清單 1 所示類似。在這個示例中,最常見的單詞長度是 9 個字母,該字典中有 32,380 個匹配單詞。該字典中不包括 25 個字母或更長的單詞,并且最長的單詞并不是您覺得的 21 個字母長的 disestablishmentarian(有 81 個同樣長度的單詞,包括 superincomprehensible 和 phoneticohieroglyphic),這個 UNIX 字典中最長的單詞有 5 個,包括 pathologicopsychological。?和記娛h188下載app

清單 1. 謀略字典中 X 個字母的單詞的個數

$ for i in `seq 1 32`

> {

>  echo "There are" `egrep '^.{'$i'}$' /usr/dict/words \

| wc -l` "$i-letter words in the dictionary."

> }

There are 52 1-letter words in the dictionary.

There are 155 2-letter words in the dictionary.

There are 1351 3-letter words in the dictionary.

There are 5110 4-letter words in the dictionary.

There are 9987 5-letter words in the dictionary.

There are 17477 6-letter words in the dictionary.

There are 23734 7-letter words in the dictionary.

There are 29926 8-letter words in the dictionary.

There are 32380 9-letter words in the dictionary.

There are 30867 10-letter words in the dictionary.

There are 26011 11-letter words in the dictionary.

There are 20460 12-letter words in the dictionary.

There are 14938 13-letter words in the dictionary.

There are 9762 14-letter words in the dictionary.

There are 5924 15-letter words in the dictionary.

There are 3377 16-letter words in the dictionary.

There are 1813 17-letter words in the dictionary.

There are 842 18-letter words in the dictionary.

There are 428 19-letter words in the dictionary.

There are 198 20-letter words in the dictionary.

There are 82 21-letter words in the dictionary.

There are 41 22-letter words in the dictionary.

There are 17 23-letter words in the dictionary.

There are 5 24-letter words in the dictionary.

There are 0 25-letter words in the dictionary.

There are 0 26-letter words in the dictionary.

There are 0 27-?和記娛h188下載appletter words in the dictionary.

There are 0 28-letter words in the dictionary.

There are 0 29-letter words in the dictionary.

There are 0 30-letter words in the dictionary.

There are 0 31-letter words in the dictionary.

There are 0 32-letter words in the dictionary.

$

匹配單詞

環抱字符 \ 是異常有用的模式構造器:它們將要匹配的全部單詞 括起來,這表示,它們不會匹配帶括號的模式,除非該模式本身便是一個單詞。單詞 定義為兩側由非單詞字符描述的、隨意率性數目組成單詞的字符(數字、字母和下劃線字符)。非單詞字符包括下面的所有字符:

行首

空缺字符

標點符號

行尾

任何除字母、數字或下劃線以外的字符

這些環抱字符可以節省大年夜量的光陰,然則它們經常沒有被充分地使用,可能是由于并非所有的正則表達式實現都支持它們。假如您的正則表達式實現支持它們,那么您應該慢慢養成應用它們的習氣。

將必要零丁匹配的單詞括起來,如下所示:

\

這個示例中的正則表達式不會匹配單詞 ecosystem、systemic 或 system/70,也不會匹配模式 system 呈現在行中隨意率性位置的那些行,它將僅僅 匹配 system 作為自力的單詞呈現的那些行。

環抱字符與圓括號中的分組結合在一路,可以用來匹配部分 單詞。

要匹配包孕以 pre 開首 的單詞的那些行,可以應用:

\

前面的示例將匹配包孕單詞 preface 和 preposterous 的行,但不會匹配 spread 或 Dupre。

匹配重復單詞

這里先容一種應用單詞環抱字符匹配重復單詞的快速措施,重復單詞表示一個單詞在空格之后再次呈現。您還可以應用逆向引用,這是大年夜多半盛行的正則表達式實現中的一種遞歸特點,它可以匹配模式本身的某一部分。(將模式中必要引用的部分應用圓括號括起來,然后應用反斜杠加上必要進行引用的環抱字符編號來調用逆向引用:1 表示第一個圓括號分組,2 表示第二個圓括號分組,依此類推。)

要查找重復的單詞,搜索在隨意率性數目的空格之后再次呈現該單詞的環境,可以經由過程對第一個應用圓括號的部分進行逆向引用來實現:

(\)( )+\1

這個示例匹配縮寫形式和任何類型的單詞,然則它不會匹配由標點符號分隔的重復單詞,如 It's been a long, long time。

要匹配所有的重復單詞,包括由空格和 隨意率性標點符號分隔的重復單詞,可以應用下面的表達式:

(\).?( )+\1

假如必要對這些正則表達式應用 grep,則務必應用 -i 標志,以便在搜索中不區分大年夜小寫。

匹配小時

讓我們再來看別的一類常見的問題:光陰和日期。這里先容了一些設計匹配精確模式的正則表達式所必要斟酌的事變。

您無法搜索任何兩位的數字來匹配分鐘和秒,由于它們僅僅是從 0 到 59,要匹配它們,您必要應用方括號將表示十位和個位的范圍括起來:

要匹配標準的 12 或 24 小時款式的小時,可以應用下面的表達式:

(([0-1]?[0-9])|([2][0-3])):([0-5][0-9])(:[0-5][0-9])?

要匹配 12 小時 AM/PM 款式、帶或不帶秒數的光陰,以致匹配大年夜寫或小寫、?和記娛h188下載app不帶后綴 AM 或 PM 標識符的光陰,可以應用下面的表達式:

([^0-9])([0-1]?[0-9]){1}(((:([0-5]){1}([0-9]){1}){1,2})|(( )?([AP]M)|([ap]m)))?

假如在上一個示例中沒有開始的否定語句,它將匹配不帶冒號的光陰,這將取決于輸入數據,可能會匹配中波廣播電臺(在美國稱為調幅 AM 電臺),如 1450 AM。

匹配月份

匹配 12 個月中的任何月份必要一個應用 | 操作符進行分隔的列表,但無意偶爾會應用不合的要領對日期進行縮寫:

要查找完備拼寫或三字母縮寫的 12 個月份,可以應用下面的表達式(位于一行):

Jan(uary)?|Feb(uary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|

Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?

您可以加以想象并搜索完備拼寫或三字母縮寫的變形,即僅當后面緊隨著一個空格或點號的環境,可以應用下面的表達式(位于一行):

Jan(uary| |\.)|Feb(uary| |\.)|Mar(ch| |\.)|Apr(il| |\.)|May( |\.)|Jun(e| |\.)|Jul(y| |\

.)|Aug(ust| |\.)|Sep(tember| |\.)|Oct(ober| |\.)|Nov(ember| |\.)|Dec(ember| |\.)

請留意,在上面的這兩個示例中,May 是一個特殊的例外。在所有的月份中,它是獨一的完備拼寫與三字母縮寫相同的月份,以是成功的匹配必須包孕這兩種變形中的任何一種 作為其縮寫,是以像“Mayflower”這樣的單詞不會導致誤報。

當匹配模式前面的字符不是空格或行首時,這些示例照樣會掉?。ǚ祷卣`報的結果)。這不太可能會呈現在英語散文中,然則可能呈現在法度榜樣源代碼中,由于此中可能應用了像 NumOct 這樣的變量名。

要修復這些問題,可以履行下面的操作:

應用圓括號將全部正則表達式括起來,并在它的前面加上另一個限制符,用于匹配行首或者空格字符,如下所示(位于一行):

(^| )(Jan(uary| |\.)|Feb(uary| |\.)|Mar(ch| |\.)|Apr(il| |\.)|

May( |\.)|Jun(e| |\.)|Jul(y| |\.)|Aug(ust| |\.)|Sep(tember| |

\.)|Oct(ober| |\.)|Nov(ember| |\.)|Dec(ember| |\.))

另一種完成這個義務的措施是,在該正則表達式的前面加上一個限制符,以匹配非翰墨數字的字符,如下所示(位于一行):

([^A-Za-z0-9])(Jan(uary| |\.)|Feb(uary| |\.)|Mar(ch| |\.)|

Apr(il| |\.)|May( |\.)|Jun(e| |\.)|Jul(y| |\.)|Aug(ust| |\.)|

Sep(tember| |\.)|Oct(ober| |\.)|Nov(ember| |\.)|Dec(ember| |\.))

然則仍舊存在潛在的問題,對付搜索整篇英文散文,這些示例并弗成靠,由于它們可能返回差錯的匹配結果,如“Janelle”或“Augury”這樣的單詞。要修復這個問題,您必須應用單詞環抱字符將每個月份括起來。

本文開首提到,精確的正則表達式應該僅返回必要匹配的數據,以便在輸入中掃除其他不需要的內容。這種措詞是顛末仔細斟酌的,由于對付構建正則表達式來說,這與高低文有關。對付有些環境,前面的示例異常得當,無需添加額外的單詞環抱字符。在其他的環境下,可以對其進行相稱程度的簡化,例如,假如您正在搜索僅包孕大年夜寫的日期數值數據的日志文件,那么只必要應用像 [A-S] 這樣的正則表達式來匹配包孕月份名稱的行。

匹配日期

您可以結合一些表 1 所示的數量匹配來匹配日期。

要匹配“month, day, years”,可以應用下面的正則表達式(由于撇號字符是該正則表達式的一部分,以是必須應用雙引號將它括起來,如下所示):

"[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2})"

這個正則表達式匹配 9 種不合的日期款式:

MONTH [D]D, YY

MONTH [D]D, 'YY

MONTH [D]D, YYYY

MON. [D]D, YY

MON. [D]D, 'YY

MON. [D]D, YYYY

MON [D]D, YY

MON [D]D, 'YY

MON [D]D, YYYY

這個正則表達式的誤報包括“Order 99, 99”,要打消這些誤報,可以將這個正則表達式與用于月份的正則表達式結合起來,如上所述,以便能夠僅匹配實際的月份名稱。別的,變動數值范圍以避免差錯的匹配,并且經由過程使逗號成為可選項,重復了 18 種可能的款式。

這將獲得一個很長的正則表達式??荚嚋y驗下面的表達式:

"([^A-Za-z0-9])(Jan(uary| |\.)|Feb(uary| |\.)|Mar(ch| |\.)|

Apr(il| |\.)|May( |\.)|Jun(e| |\.)|Jul(y| |\.)|Aug(ust| |\.)|

Sep(tember| |\.)|Oct(ober| |\.)|Nov(ember| |\.)|

Dec(ember| |\.)) [0-3]?[0-9]{1}(,)? ([0-9]{4}|'?[0-9]{2})"

同樣,根據您的必要仔細設計正則表達式。匹配模式平日對照輕易,這是由于它存在于特定輸入的高低文中,而不是由于它可能自力于數據集而存在。后代人將會發明,前面那個很長的正則表達式中仍舊存在 Y10K 差錯,由于它能匹配的最大年夜可能的年份為 9999。

匹配整數

正如您在前幾個示例中看到的,應用方括號中的范圍可以很好地匹配數值。

要匹配隨意率性長度的整數,可以在數值范圍后面加上 +;要包括負值,可以在它的前面加上可選的負號(連字號)匹配:

-?[0-9]+

前面的例子可以匹配 0,由于 0 是指定范圍中可選的字符。

對付數值匹配,應用圓括號將某些部分括起來也異常有效。要匹配隨意率性的十進制數值,可以應用包孕小數點加上一個或多個數值的可選環抱字符,以此對前面的正則表達式進行擴展:

-?[0-9]+(\.[0-9]+)?

可以應用方括號指定十進制數值的小數位數。例如,要匹配小數位數為 5 或更多小數位數的正數值,可以應用下面的表達式:

[^-][0-9]+\.([0-9]){5,}

更多實際的匹配

范圍加上應用括號括起來的元字符,在查找相符任何特定款式的數值時異常有用。將前面先容的一些技巧結合起來,可以構建匹配各類數據的正則表達式:

要匹配美國的電話號碼,可以應用:

((\([2-9][0-9]{2}\))?\ ?|[2-9][0-9]{2}(?:\-?|\ ?))[2-9][0-9]{2}[- ]?[0-9]{4}

這個正則表達式可以匹配美國 15 種款式的電話號碼:

(NPA) PRE-SUFF

(NPA) PRE SUFF

(NPA) PRESUFF

(NPA)PRE-SUFF

(NPA)PRE SUFF

(NPA)PRESUFF

NPA PRE-SUFF

NPA PRE SUFF

NPA PRESUFF

N?和記娛h188下載appPAPRE-SUFF

NPAPRE SUFF

NPAPRESUFF

PRE-SUFF

PRE SUFF

PRESUFF

它還可以匹配美國免費 WATS 號碼,只管 1-800 的“1-”前綴或其他的免費號碼不是匹配的一部分,但它本身可以匹配 10 位的數值。對付以 1 或 1+ 開首的美國號碼和隨意率性數目的空格,也完全一樣,長途電話撥號前綴本身無法匹配,然則只要它后面隨實在際的號碼,這個正則表達式就能夠將其找出來。

要匹配兩或三位域的電子郵件地址,可以考試測驗下面的表達式:

\@[a-zA-Z_\.]+?\.[a-zA-Z]{2,3}

要匹配如今所有盛行的 URL,可以應用下面的正則表達式:

(((http(s)?|ftp|telnet|news)://|mailto:)[^\(\)[:space:]]+)

這個表達式可以正常運行,然則匹配 URL 并不像您想象的那么簡單。匹配任何可能的 URL 的正則表達式,如 RFC 1738 中的定義,頒發在“Regexp for URLs”(請拜見參考資料部分)一文中,它異常偉大年夜并且看起來令人生畏?,F在應該將它合并為一個 [:url:] 類(假如有用于處置懲罰類似數據種類的各類新的類,如 [:email:],那就好了)。

停止語

本文涉及到一些用于編寫正則表達式的模式構建技巧,以及若何應用它們來完成治理員時常碰著的特定類型數據匹配的事情。在此歷程中,向您先容了大年夜量有代價的實際正則表達式,您可以將它們添加到自己的治理對象庫中。

免責聲明:以上內容源自網絡,版權歸原作者所有,如有侵犯您的原創版權請告知,我們將盡快刪除相關內容。

您可能還會對下面的文章感興趣:

快三平台开户