① 正則表達式特殊符號及用法
Python3 正則表達式特殊符號及用法(詳細列表)
正則表達式的強大之處在於特殊符號的應用,特殊符號定義了字元集合、子組匹配、模式重復次數。正是這些特殊符號使得一個正則表達式可以匹配字元串集合而不只是一個字元串。
注1:為了便於理解,難點的地方均用 斜體 舉了栗子。
注2:如果你對正則表達式一頭霧水或者看不懂下邊這個列表,那麼小甲魚極力推薦你先學習這個: Python3 如何優雅地使用正則表達式
字螞賣符 含義
. 表示匹配除了換行符外的任何字元
註:通過設置 re.DOTALL 標志可以使 . 匹配任何字元(包含換行符)
A | B, 表示匹配正則表達式 A 或者 B
^ 1. (脫字元)匹配輸入字元串的開始位置
2. 如果設置了 re.MULTILINE 標志,^ 也匹配換行符之後的位置
$ 1. 匹配輸入字元串的結束位置
2. 如果設置了 re.MULTILINE 標志,$ 也匹配換行符之前的位置
\ 1. 將一個普通字元變成特殊字元,例如 \d 表示匹配所有十進制數字
2. 解除元字元的特殊功能,例如 \. 表示匹配點號本身
3. 引用序號對應的子組所匹配的字元串
4. 詳見下方列舉
[...] 字元類,匹配所包含的任意一個字元
注1:連字元 - 如果出現在字元串中間表示字元范圍描述;如果如果出現在首位則僅作為普通字元
注2:特殊字元僅有反斜線 \ 保持特殊含義,用於轉義字元。其它特殊字元如 *、+、? 等均作為普通字元匹配
注3:脫字元 ^ 如果出現在首位則表示匹配不包含其中的任意字元;如果 ^ 出現在字元串中間就僅作為普通字元匹配
{M,N} M 和 N 均為非負整數,其中 M <= N,表示前邊的 RE 匹配 M ~ N 次
注1:{M,} 表示至少匹配 M 次
注2:{,N} 等價於 {0,N}
注3:{N} 表示需要匹配 N 次
* 匹配前面的子表達式零次或多次,等價於 {0,}
+ 匹配前面的子表達式一次或多次,等價於 {1,}
? 匹配前面的子表達式零次或一次,等價於 {0,1}
*?, +?, ??默認情況下 *、+ 和 ? 的匹配模式是貪婪模式(即會盡可能多地匹配符合規則的字元串);*?、+? 和 ?? 表示啟用對應的非貪婪模式。
舉個栗子:對於字元串 "FishCCC",正則表達式 FishC+ 會匹配整個字元串,而 FishC+? 則匹配 "FishC"。
{M,N}? 同上,啟用非貪婪模式,即只匹配 M 次
(...) 匹配圓括弧中的正則表達式,或者指定一個子組的開始和結束位置
註:子組的內容可以在匹配之後被 \數字 再次引用
舉個栗子:(\w+) \1 可以字元串 "FishC FishC.com" 中的 "FishC FishC"(注意有空格)
(?...)(? 開頭的表示為正則表達式的擴展語法(下邊這些是 Python 支持的所有擴展語法)
(?aiLmsux)1. (? 後可以緊跟著 'a','i','L','m','s','u','x' 中的一個或多個字元,只能在正則表達式的開頭使用
2. 每一個字元對應一種匹配標志:re-A(只匹配 ASCII 字元),re-I(忽略大小寫),re-L(區域設置),re-M(多行模式), re-S(. 匹配任何符號),re-X(詳細表達式),包含這些字元將會影響整個正則表達式的規則
3. 當你不想通過 re.compile() 設置正則表達式標志,這種方法就非常有用啦
注意,由於 (?x) 決定正則表達式如何被解析,所以它應該總是被放在最前邊(最多允許前邊有空白符)。如果 (?x) 的前邊是非空白字元,那麼 (?x) 就發揮不了作用了。
(?:...)非捕獲組,即該子組匹配的字元串無法從後邊獲取
(?P<name>...)命名組,通過組的名字(name)即可訪問到子組匹配的字元串
(?P=name)反向引用一個命名組,它匹配指定命名組匹配的任何孫物州內容
(?#...)注釋,括弧中的內容將被忽略
(?=...)前向肯定斷言。如果當前包含的正則表達式(這里以 ... 表示)在當前位置成功匹配,則代表成功,否則失敗。一旦該部分正則表達式被匹配引擎嘗試過,就不會繼續進行匹配則蔽了;剩下的模式在此斷言開始的地方繼續嘗試。
舉個栗子:love(?=FishC) 只匹配後邊緊跟著 "FishC" 的字元串 "love"
(?!...)前向否定斷言。這跟前向肯定斷言相反(不匹配則表示成功,匹配表示失敗)。
舉個栗子:FishC(?!\.com) 只匹配後邊不是 ".com" 的字元串 "FishC"
(?<=...)後向肯定斷言。跟前向肯定斷言一樣,只是方向相反。
舉個栗子:(?<=love)FishC 只匹配前邊緊跟著 "love" 的字元串 "FishC"
(?<!...)後向否定斷言。跟前向肯定斷言一樣,只是方向相反。
舉個栗子:(?<!FishC)\.com 只匹配前邊不是 "FishC" 的字元串 ".com"
(?(id/name)yes-pattern|no-pattern)1. 如果子組的序號或名字存在的話,則嘗試 yes-pattern 匹配模式;否則嘗試 no-pattern 匹配模式
2. no-pattern 是可選的
舉個栗子:(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$) 是一個匹配郵件格式的正則表達式,可以匹配 和 '[email protected]',但是不會匹配 ''
\下邊列舉了由字元 '\' 和另一個字元組成的特殊含義。注意,'\' + 元字元的組合可以解除元字元的特殊功能
\序號1. 引用序號對應的子組所匹配的字元串,子組的序號從 1 開始計算
2. 如果序號是以 0 開頭,或者 3 個數字的長度。那麼不會被用於引用對應的子組,而是用於匹配八進制數字所表示的 ASCII 碼值對應的字元
舉個栗子:(.+) \1 會匹配 "FishC FishC" 或 "55 55",但不會匹配 "FishCFishC"(注意,因為子組後邊還有一個空格)
\A匹配輸入字元串的開始位置
\Z匹配輸入字元串的結束位置
\b匹配一個單詞邊界,單詞被定義為 Unidcode 的字母數字或下橫線字元
舉個栗子:\bFishC\b 會匹配字元串 "love FishC"、FishC." 或 "(FishC)"
\B匹配非單詞邊界,其實就是與 \b 相反
舉個栗子:py\B 會匹配字元串 "python"、"py3" 或 "py2",但不會匹配 "py "、"py." 或 "py!"
\d1. 對於 Unicode(str 類型)模式:匹配任何一個數字,包括 [0-9] 和其他數字字元;如果開啟了 re.ASCII 標志,就只匹配 [0-9]
2. 對於 8 位(bytes 類型)模式:匹配 [0-9] 中任何一個數字
\D匹配任何非 Unicode 的數字,其實就是與 \d 相反;如果開啟了 re.ASCII 標志,則相當於匹配 [^0-9]
\s1. 對於 Unicode(str 類型)模式:匹配 Unicode 中的空白字元(包括 [ \t\n\r\f\v] 以及其他空白字元);如果開啟了 re.ASCII 標志,就只匹配 [ \t\n\r\f\v]
2. 對於 8 位(bytes 類型)模式:匹配 ASCII 中定義的空白字元,即 [ \t\n\r\f\v]
\S匹配任何非 Unicode 中的空白字元,其實就是與 \s 相反;如果開啟了 re.ASCII 標志,則相當於匹配 [^ \t\n\r\f\v]
\w1. 對於 Unicode(str 類型)模式:匹配任何 Unicode 的單詞字元,基本上所有語言的字元都可以匹配,當然也包括數字和下橫線;如果開啟了 re.ASCII 標志,就只匹配 [a-zA-Z0-9_]
2. 對於 8 位(bytes 類型)模式:匹配 ASCII 中定義的字母數字,即 [a-zA-Z0-9_]
\W匹配任何非 Unicode 的單詞字元,其實就是與 \w 相反;如果開啟了 re.ASCII 標志,則相當於 [^a-zA-Z0-9_]
轉義符號正則表達式還支持大部分 Python 字元串的轉義符號:\a,\b,\f,\n,\r,\t,\u,\U,\v,\x,\\
注1:\b 通常用於匹配一個單詞邊界,只有在字元類中才表示「退格」
注2:\u 和 \U 只有在 Unicode 模式下才會被識別
注3:八進制轉義(\數字)是有限制的,如果第一個數字是 0,或者如果有 3 個八進制數字,那麼就被認為是八進制數;其他情況則被認為是子組引用;至於字元串,八進制轉義總是最多隻能是 3 個數字的長度
② 求教C#正則表達式
什麼是正則表達式
在編寫字元串的處理程序時,經常會有查找符合某些復雜規則的字元串的需要。正則表達式就是用於描述這些規則的工具。換句話說或羨,正則表達式就是記錄文本規則的代碼。
通常,我們在使用WINDOWS查找文件時,會使用通配符(*和?)。如果你想查找某個目錄下的所有Word文檔時,你就可以使用*.doc進行查找,在這里,*就被解釋為任意字元串。和通配符類似,正則衫仔拍表達式也是用來進行文本匹配的工具,只不過比起通配符,它能更精確地描述你的需求——當然,代價就是更復雜。
l 一個簡單的例子——驗證電話號碼
學習正則表達式的最好方法是從例子開始,下面我們從驗證電話號碼開始,一步一步的了解正則表達式。
在我們國家,電話號碼(如:0379-65624150)通常包含3到4為以0開頭的區號和一個7或8為的號碼,中間通常以連字元』-』隔開。在這個例子中,首先我們要介紹一個元字元\d,它用來匹配一個0到9的數字。這個正則表達式可以寫成:^0\d{2,3}-\d{7,8}$
我們來對他進行分析,0匹配數字「0」,\d匹配一個數字,{2,3}表示重復2到3次,-只匹配」-」自身,接下來的\d同樣匹配一個數字,而 {7,8}則表示重復7到8次。當然,電話號碼還可以寫成 (0379)65624150,這里就交給讀者完成。
l 元字元
在上面的例子中,我們接觸到了一個元字元\d,正如你所想的,正則表達式還有很多像\d一樣的元字元,下表列出了一些常用的元字元:
元字元
說明
.
匹配除換行符以外的任意字元
\b
匹配單詞的開始或結束
\d
匹配數字
\s
匹配任意的空白符
\w
匹配字母或數字或下劃線或漢字
^
匹配字元串的開始
$
匹配字元串的結束
表1、常用的元字元
l 轉義字元
如果你想查找元字元本身的話,比如你查找.,或者*,就出現了問題:你沒辦法指定它們,因為它們會被解釋成別的意思。這時你就得使用\來取消這些字元的特殊意義。因此,你應該使用\.和\*。當然,要查找\本身,你也得用\\.
例如:unibetter\.com匹配unibetter.com,C:\\Windows匹配C:\Windows。
l 限定符
限定符又叫重復描述字元,表示一個字元要出現的次數。比如我們在匹配電話號碼時使用的{3,4}就表示出現3到4次。常用的限定符有:
限定符
說明
*
重復零次或更多次
+
重復一次或更多次
?
重復零次或一次
{n}
重復n次
{n,}
重復n次或更多次
{n,m}
重復n到m次
表2、常用的限定符
二、.NET中正則表達式的支持
System.Text.RegularExpressions 命名空間包含一些類,這些類提供對 .NET Framework 正則表達式引擎的訪問。該命名空間提供正則表達式功能,可以從運行在 Microsoft .NET Framework 內的任何平台或語言中使用該功能。
1、在C#中使用正則表達式
在了解了C#中支持正則表達式的類後,我們一起來將上面提到的驗證電話號碼的正則表達式寫入C#代碼中,實現電話號碼的驗證。
第一步,建立一個名為SimpleCheckPhoneNumber的Windows項目。
第二步,引入System.Text.RegularExpressions命名空間。
第三步,寫戚純出正則表達式。這里的正則表達式就是上面的驗證號碼的字元串。由於上面的字元串只能驗證用連字元連接區號和號碼的方式的電話號碼,所以我們做了一些修改:0\d{2,3}-\d{7,8}|\(0\d{2,3}\)\d{7,8}。在這個表達式中,| 號面的一部分是我們上面提到過的,後面一部分是用來驗證(0379)65624150這種電話號碼寫法的。由於 ( 和 ) 也是元字元,所以要用轉義字元。| 表示分支匹配,要麼匹配前面的一部分,要麼匹配後面的一部分。
第四步,正則表達式構造一個Regex類。
第五步,使用Regex類的IsMatch方法驗證匹配。Regex類的IsMatch()方法返回一個bool值,如果有匹配項,返回true,否則返回false。
、正則表達式進階
l 分組
在匹配電話號碼的時候,我們已經用到過重復單個字元。下面我們來了解如何使用分組來匹配一個IP地址。
眾所周知,IP地址是四段點分十進制的字元串表示的。所以,我們可以通過地址的分組,來進行匹配。首先,我們來匹配第一段:2[0-4]\d|25[0-5]|[01]?\d\d? 這段正則表達式可以匹配IP地址的一段數字。2[0-4]\d 匹配以2開頭,十位為0到4,個位為任何數字的三位欄位,25[0-5] 匹配以25 開頭,個位為0到5 的三位欄位,[01]?\d\d? 匹配任何以1者0頭,個位和十位為任何數子的欄位。? 表示出現零次或一次。所以, [01] 和 最後一個 \d 都可以不出現,如果我們再向這個字元串後面添加一個 \. 來匹配 . 就可以劃分一個段了。現在,我們把 2[0-4]\d|25[0-5]|[01]?\d\d?\. 當做一個分組,就可以寫成 (2[0-4]\d|25[0-5]|[01]?\d\d?\.) 。接下來我們就來使用這個分組。將這個分組重復兩次,然後,再使用 2[0-4]\d|25[0-5]|[01]?\d\d? 就可以了。完整的正則表達式為: (2[0-4]\d|25[0-5]|[01]?\d\d?\.){3}2[0-4]\d|25[0-5]|[01]?\d\d?
l 後向引用
在我們了解分組以後,我們就可以使用後向引用了。所謂後向引用,就是使用前面捕獲的結果,對後面的字元進行匹配。多用於匹配重復字元。比如匹配 go go 這樣的重復字元。我們就可以使用 (go) \1來進行匹配。
默認情況下,每個分組會自動擁有一個組號,規則是:從左向右,以分組的左括弧為標志,第一個出現的分組的組號為1,第二個為2,以此類推。當然,你也可以自己指定子表達式的組名。要指定一個子表達式的組名,請使用這樣的語法:(?<Word>\w+)(或者把尖括弧換成'也行:(?'Word'\w+)),這樣就把\w+的組名指定為Word了。要反向引用這個分組捕獲的內容,你可以使用\k<Word>,所以上一個例子也可以寫成這樣:\b(?<Word>\w+)\b\s+\k<Word>\b。
自定義組名還有另外一個好處,在我們的C#程序中,如果需要得到分組的值,我們就可以很明確的使用我們定義的分組的名字來得到,而不必使用下標。
當我們並不想使用後向引用時,是不需要捕獲組記憶任何東西的,這種情況下就可以利用(?:nocapture)語法來主動地告訴正則表達式引擎,不要把圓括弧的內容當作捕獲組,以便提高效率。
l 零寬斷言
在前面的元字元介紹中,我們已經知道了有這樣一類字元,可以匹配一句話的開始、結束(^ $)或者匹配一個單詞的開始、結束(\b)。這些元字元只匹配一個位置,指定這個位置滿足一定的條件,而不是匹配某些字元,因此,它們被成為 零寬斷言。所謂零寬,指的是它們不與任何字元相匹配,而匹配一個位置;所謂斷言,指的是一個判斷。正則表達式中只有當斷言為真時才會繼續進行匹配。
在有些時候,我們精確的匹配一個位置,而不僅僅是句子或者單詞,這就需要我們自己寫出斷言來進行匹配。下面是斷言的語法:
斷言語法
說明
(?=pattern)
前向肯定斷言,匹配pattern前面的位置
(?!pattern)
前向否定斷言,匹配後面不是pattern的位置
(?<=pattern)
後向肯定斷言,匹配pattern後面的位置
(?<!pattern)
後向否定斷言,匹配前面不是pattern的位置
表3、斷言的語法及說明
很難理解嗎?我們來看一個例子。
有一個標簽:<book>,我們想要得到標簽<book>的標簽名(book),這個時候,我們就可以使用斷言來處理。看下面這個表達式:(?<=\<)(?<tag>\w*)(?=\>) ,使用這個表達式,可以匹配< 和 >之間的字元,也就是這里的book。使用斷言還還可以寫出更加復雜的表達式,這里就不再舉例了。
還有一點非常重要,就是斷言語法所使用的圓括弧並不作為捕獲組,所以不能使用編號或命名來對它進行引用。
l 貪婪與懶惰
當正則表達式中包含能接受重復的限定符時,通常的行為是(在使整個表達式能得到匹配的前提下)匹配盡可能多的字元。來看一下這個表達式:a\w*b ,用它來匹配字元串 aabab 時,得到的匹配結果是 aabab 。這種匹配被稱為貪婪匹配。
有些時候,我們希望讓它盡可能的少重復,即用上面的例子得到的匹配結果是 aab,這時我們就要使用懶惰匹配。懶惰匹配需要在重復限定符的後面添加一個 ? 符號,上面的表達式就可以寫成:a\w*?b 我們再來匹配字元串 aabab時,得到的匹配結果是 aab 和 ab。
也許這個時候你要問,ab 比aab重復次數更少,為什麼不先匹配ab呢?其實在正則表達式中還有比貪婪/懶惰優先順序更高的規則:最先開始的匹配擁有最高的優先權——The match that begins earliest wins。
l 注釋
語法:(?#comment)
例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)
注意:如果使用注釋,則需要格外注意不要在注釋的小括弧前面出現空格、換行符等一些字元,如果可以忽略這些字元,則最好使用「忽略模式里的空白符」選項,即C#中RegexOptions枚舉的IgnorePatternWhitespace選項(C#中的RegexOptions枚舉下面將會提到)。
l C#中的處理選項
在C#中,可以使用RegexOptions 枚舉來選擇C#對正則表達式的處理方式。下面是MSDN中RegexOptions 枚舉的成員介紹:
l C#中Capture類、Group類、Match類
Capture類:表示單個子表達式捕獲中的結果。Capture類表示單個成功捕獲中的一個子字元串。該類沒有公共構造函數,可以從Group類或者Match類中得到一個Capture類的對象集合。Capture類有三個常用屬性,分別是Index、Length和Value。Index表示捕獲的子字元串的第一個字元的位置。Length表示捕獲的子字元串的長度,Value表示捕獲的子字元串。
Group類:表示正則表達式中分組的信息。該類提供了對分組匹配的正則表達式的支持。該類沒有公共構造函數。可以從Match類中得到一個Group類的集合。如果正則表達式中的分組已命名,則可以使用名字對其進行訪問,如果沒有命名,則可以採用下標訪問。注意:每一個Match的Groups集合中的第0個元素(Groups[0])都是這個Match捕獲的字元串,也是Capture的Value。
Match類:表示單個正則表達式匹配的結果。該類同樣沒有公共構造函數,可以從Regex類的Match()方法得到該類的一個實例,也可以使用Regex類的Matches()方法得到給類的一個集合。
這三個類都能表示單個正則表達式匹配的結果,但Match類得到的更為詳細,包含捕獲和分組信息。所以,Match類在這個三個類中是最常用的。
③ C語言怎麼用正則表達式
由於它可以極大地簡化處理字元串時的掘咐漏復雜度,因此現在已經在許多 L i n u x 實用工具中得到了應用。千萬不要以為正則表達式只是 P e r l 、 P y t h o n 、 B a s h 等腳本語言的專利,作為 C 語言程序員,用戶同樣可以在自己的程序中運用正則表達式。標準的 C 和 C + + 都不支持正則表達式,但有一些函數庫可以輔助 C / C + + 程序員完成這一功能,其中最著名的當數 P h i l i p H a z e l 的 P e r l - C o m p a t i b l e R e g u l a r E x p r e s s i o n 庫,許多 L i n u x 發行版本都帶有這個函數庫。編譯正則表達式為了提高效率,在將一個字元串與正則表達式進行比較之前,首先要用 r e g c o m p ( ) 函數對它進行編譯,將其轉化為 r e g e x _ t 結構: i n t r e g c o m p ( r e g e x _ t * p r e g , c o n s t c h a r * r e g e x , i n t c f l a g s ) ; 參數 r e g e x 是一個字元串,它代表將要被編譯的正則表達式;參數 p r e g 指向一個聲明為 r e g e x _ t 的數據結構,用來保存編譯結果;參數 c f l a g s 決定了正則表達式該如何被處理的細節。判爛如果函數 r e g c o m p ( ) 執行成功,並且編譯結果被正確填充到 p r e g 中後,函數將返回 0 ,任何其它的返回結果都代表有某種錯簡爛誤產生。匹配正則表達式一旦用 r e g c o m p ( ) 函數成功地編譯了正則表達式,接下來就可以調用 r e g e x e c ( ) 函數完成模式匹配: i n t r e g e x e c ( c o n s t r e g e x _ t * p r e g , c o n s t c h a r * s t r i n g , s i z e _ t n m a t c h , r e g m a t c h _ t p m a t c h [ ] , i n t e f l a g s ) ; t y p e d e f s t r u c t { r e g o f f _ t r m _ s o ; r e g o f f _ t r m _ e o ; } r e g m a t c h _ t ; 參數 p r e g 指向編譯後的正則表達式,參數 s t r i n g 是將要進行匹配的字元串,而參數 n m a t c h 和 p m a t c h 則用於把匹配結果返回給調用程序,最後一個參數 e f l a g s 決定了匹配的細節。在調用函數 r e g e x e c ( ) 進行模式匹配的過程中,可能在字元串 s t r i n g 中會有多處與給定的正則表達式相匹配,參數 p m a t c h 就是用來保存這些匹配位置的,而參數 n m a t c h 則告訴函數 r e g e x e c ( ) 最多可以把多少個匹配結果填充到 p m a t c h 數組中。當 r e g e x e c ( ) 函數成功返回時,從 s t r i n g + p m a t c h [ 0 ] . r m _ s o 到 s t r i n g + p m a t c h [ 0 ] . r m _ e o 是第一個匹配的字元串,而從 s t r i n g + p m a t c h [ 1 ] . r m _ s o 到 s t r i n g + p m a t c h [ 1 ] . r m _ e o ,則是第二個匹配的字元串,依此類推。釋放正則表達式無論什麼時候,當不再需要已經編譯過的正則表達式時,都應該調用函數 r e g f r e e ( ) 將其釋放,以免產生內存泄漏。 v o i d r e g f r e e ( r e g e x _ t * p r e g ) ; 函數 r e g f r e e ( ) 不會返回任何結果,它僅接收一個指向 r e g e x _ t 數據類型的指針,這是之前調用 r e g c o m p ( ) 函數所得到的編譯結果。如果在程序中針對同一個 r e g e x _ t 結構調用了多次 r e g c o m p ( ) 函數, P O S I X 標准並沒有規定是否每次都必須調用 r e g f r e e ( ) 函數進行釋放,但建議每次調用 r e g c o m p ( ) 函數對正則表達式進行編譯後都調用一次 r e g f r e e ( ) 函數,以盡早釋放佔用的存儲空間。報告錯誤信息如果調用函數 r e g c o m p ( ) 或 r e g e x e c ( ) 得到的是一個非 0 的返回值,則表明在對正則表達式的處理過程中出現了某種錯誤,此時可以通過調用函數 r e g e r r o r ( ) 得到詳細的錯誤信息。 s i z e _ t r e g e r r o r ( i n t e r r c o d e , c o n s t r e g e x _ t * p r e g , c h a r * e r r b u f , s i z e _ t e r r b u f _ s i z e ) ; 參數 e r r c o d e 是來自函數 r e g c o m p ( ) 或 r e g e x e c ( ) 的錯誤代碼,而參數 p r e g 則是由函數 r e g c o m p ( ) 得到的編譯結果,其目的是把格式化消息所必須的上下文提供給 r e g e r r o r ( ) 函數。在執行函數 r e g e r r o r ( ) 時,將按照參數 e r r b u f _ s i z e 指明的最大位元組數,在 e r r b u f 緩沖區中填入格式化後的錯誤信息,同時返回錯誤信息的長度。應用正則表達式最後給出一個具體的實例,介紹如何在 C 語言程序中處理正則表達式。 # i n c l u d e < s t d i o . h > ; # i n c l u d e < s y s / t y p e s . h > ; # i n c l u d e < r e g e x . h > ; / * 取子串的函數 * / s t a t i c c h a r * s u b s t r ( c o n s t c h a r * s t r , u n s i g n e d s t a r t , u n s i g n e d e n d ) { u n s i g n e d n = e n d - s t a r t ; s t a t i c c h a r s t b u f [ 2 5 6 ] ; s t r n c p y ( s t b u f , s t r + s t a r t , n ) ; s t b u f [ n ] = 0 ; r e t u r n s t b u f ; } / * 主程序 * / i n t m a i n ( i n t a r g c , c h a r * * a r g v ) { c h a r * p a t t e r n ; i n t x , z , l n o = 0 , c f l a g s = 0 ; c h a r e b u f [ 1 2 8 ] , l b u f [ 2 5 6 ] ; r e g e x _ t r e g ; r e g m a t c h _ t p m [ 1 0 ] ; c o n s t s i z e _ t n m a t c h = 1 0 ; / * 編譯正則表達式 * / p a t t e r n = a r g v [ 1 ] ; z = r e g c o m p ( & r e g , p a t t e r n , c f l a g s ) ; i f ( z ! = 0 ) { r e g e r r o r ( z , & r e g , e b u f , s i z e o f ( e b u f ) ) ; f p r i n t f ( s t d e r r , " % s : p a t t e r n ' % s ' \ n " , e b u f , p a t t e r n ) ; r e t u r n 1 ; } / * 逐行處理輸入的數據 * / w h i l e ( f g e t s ( l b u f , s i z e o f ( l b u f ) , s t d i n ) ) { + + l n o ; i f ( ( z = s t r l e n ( l b u f ) ) > ; 0 & & l b u f [ z - 1 ] = = ' \ n ' ) l b u f [ z - 1 ] = 0 ; / * 對每一行應用正則表達式進行匹配 * / z = r e g e x e c ( & r e g , l b u f , n m a t c h , p m , 0 ) ; i f ( z = = R E G _ N O M A T C H ) c o n t i n u e ; e l s e i f ( z ! = 0 ) { r e g e r r o r ( z , & r e g , e b u f , s i z e o f ( e b u f ) ) ; f p r i n t f ( s t d e r r , " % s : r e g c o m ( ' % s ' ) \ n " , e b u f , l b u f ) ; r e t u r n 2 ; } / * 輸出處理結果 * / f o r ( x = 0 ; x < n m a t c h & & p m [ x ] . r m _ s o ! = - 1 ; + + x ) { i f ( ! x ) p r i n t f ( " % 0 4 d : % s \ n " , l n o , l b u f ) ; p r i n t f ( " $ % d = ' % s ' \ n " , x , s u b s t r ( l b u f , p m [ x ] . r m _ s o , p m [ x ] . r m _ e o ) ) ; } } / * 釋放正則表達式 * / r e g f r e e ( & r e g ) ; r e t u r n 0 ; } 上述程序負責從命令行獲取正則表達式,然後將其運用於從標准輸入得到的每行數據,並列印出匹配結果。執行下面的命令可以編譯並執行該程序: # g c c r e g e x p . c - o r e g e x p # . / r e g e x p ' r e g e x [ a - z ] * ' < r e g e x p . c 0 0 0 3 : # i n c l u d e < r e g e x . h > ; $ 0 = ' r e g e x ' 0 0 2 7 : r e g e x _ t r e g ; $ 0 = ' r e g e x ' 0 0 5 4 : z = r e g e x e c ( & r e g , l b u f , n m a t c h , p m , 0 ) ; $ 0 = ' r e g e x e c ' 小結對那些需要進行復雜數據處理的程序來說,正則表達式無疑是一個非常有用的工具。本文重點在於闡述如何在 C 語言中利用正則表達式來簡化字元串處理,以便在數據處理方面能夠獲得與 P e r l 語言類似的靈活性。
④ 正則表達式「或「的使用
正則表達式,又稱規則表達式。是計算機科學的一個概念。
正則表達式通常被用來檢索、替換那些符合某個模式(規則)的文本。許多程序設計語言都支持利用正則表達式進行字元串操作。例如,在Perl中就內建了一個功能強大的正模搏旦則表達式引擎。正則表達式這個概念最初是由Unix中的工具軟體(例如sed和grep)普及開的。
正則表達式通常縮寫成「regex」,單數有regexp、regex,復數有regexps、regexes、regexen。
(4)c正則表達式使用方法擴展閱讀
正則表達式的作用:
1、匹配
檢查字元串是否符合正則表達式中的規則,有一次不匹配,則返回false。如:
String str="abc";
String reg="[a-zA-Z]\d?";//次表達式表示字元串的第一位只能是字母,第銀沖二位只能是數字或沒有boolean flag=str.matches(reg);//返回結果為true。
2、切割
所謂切割,即是按一定的規則將字元串分割成多個子字元串,如:
String str="zhangsan,lishi,wangwu"。
String reg=",";//表示以逗號作為切割符。
String[] arr=str.split(reg);//返回結果為{「zhangsan」,"lisi","wangwu}。
3、替換
即將字元串中符合規則的字元替換成指定字元,如:
String str=""。
str.replaceAll("\d{3,}","#");//表示將連續出現三個或三個以上的數字替換成「#」。
⑤ 正則表達式
regular expression是計算機科學中的一個概念。正則表達式使用單個字元串來描述匹配一系列符合某個句法規則的字元串。
g全文搜索,敏謹i忽略大小寫,m多行搜索
具有特殊意義的專用字元,用來規定其前導字元
( [ { ^ $ | ) ? * + .
不同組合中的元字元有不同的意義,舉例
可以使用[]來構建一個簡單的類
var reg = /[abc123]/;
創建一個單字元的類,代表這個字元可以是a,可以是b,可以是c,可以是1,...可以是3。
可以使用^來進行取反,
var reg = /[^abc123]/;
代表著這個單字元可以是任何其他的單字元,除了a,b,c,1,2,3之外。
如果要匹配單個字元,讓單字元只能取數字的話,可以使用字元類
寫成:
var reg = /[0123456789]/;
這么寫比較麻煩,所以可以使用范圍類,我們可以使用x-y來連接兩個字元,表示從x到y的任意字元,是個 閉區間 ,意味著 包含x和y本身 ,這樣,我們要匹配單個數字就可以寫成:
var reg2 = /[0-9]/;
要匹配所以的單個字母,可以寫為
var reg3 = /[a-zA-Z]/;
上面創建了一些類,用來表示數組,字母等。但是這么寫也比較麻煩,正則表達式提供了幾個常見的預定義類來匹配常見的字元
有了這些預定義類,寫一些正則就比較方便了,比如我們希望匹配一個ab+數字+任意字元的字元串,就可以寫作:
var reg = /abd./;
正則表達式還提供了幾個常用的邊界匹配字元
^如果不寫在[]內的話,不代表取反,代表以xxx開頭,例如: var reg = /hello/; 代表以hello開頭,相應的也有$表示為以xxx結尾,舉例說明:
單詞邊界
之前寫的方法都是一一匹配的,但是如果希望匹配一個連續出現很多次的字元,例如數字的字元串,不需要寫成 dddd ,我們可以使用量詞
使用舉例:
上面提到的{n,m},如果出現多次,只要是n-m中的值都滿足條件,到底是按照n還是m來匹配。 量詞在默認條件下是盡可能多的匹配的,即默認貪婪模式
var reg = /d{3,5}/g; '.match(reg); //{"12345","6789"}
與貪婪模式相對的,就有非貪婪模式,即盡可能少的匹配,一旦成功匹配之後不再繼續嘗試,在後面加上?即可
var reg2 = /d{3,5}?/g; '.match(reg); //{"12345","6789"}
上面的量詞解決的是單個字元重復多次的問題,如果我們需要匹配重復的多個字元,比如匹配hello出現20次,如果寫成hello{20}意味著是hell+o出現20次,o自己重復20次,而不是整個hello重復20次。
我們可以使用分組()來解備橋決這個問題,寫成:
/(hello){20}/g;
對於上面的情況,如果我們希望匹配hello或者world出現20次,可以通過使用 | 進行或操作
/(hello|world){20}/g;
舉例: good(?=Bayon) 匹配後面有Bayon的good
檢測字元串參數中是否存在正則表達式模式,存在返回true不存在返回false
用於正則表達式模式在字元串中運行查找,如果exec()找到了匹配的文本,則返回一個結果數組,否則返回null
除了數組元素和length屬性之外,exec()方法返回對象還包橋滾基括兩個屬性。
舉例說明:
search()方法用於檢索字元串中指定的子字元串,或檢索與正則表達式相匹配的子字元串。
search方法不執行全局匹配,它將忽略標志g,同時也忽略正則表達式對象的lastIndex屬性,總是返回字元串的第一個匹配的位置
match()方法將檢索字元串,以找到一個或者多個與regexp匹配的文本。regexp是否有全局g標志會影響結果。
關於string對象的replace方法,一般可以傳入兩個字元串,但是只能replace一次,如果把第一個參數傳入regexp的話,就可以是replace變得靈活。
經常使用split方法把字元串分割為字元數組
'a,b,c,d'.split(","); // ["a","b","c","d"];
相應的,也可以使用regexp進行切割:
"a1b2c3".split(/d/); // ["a","b","c","d"]
⑥ C++ 怎樣用正則表達,,
1)首先這個錯誤是在於拋出了一個regex_error的異常,你捕獲一下就可爛埋以了
2)在用字元串表示regex的時候,注意在字元串中間,\是反義字元,」\D"表示對D的轉移,顯然是錯誤的,所以如果要表示\D的正則需要使用「\\D",同樣{也是關鍵字元,表飢扮螞示為「\\{"
3)然後我測試了一缺手下(?<=<expr>)語法是regex庫解析是不支持的,我給改為了下面的pattern,是可以用的:
regex pattern(".*\\}(\\D+)\\{.*");
char* buffer="{ffff}hello world!{ffff}";
cmatch m;
if(regex_match(buffer,m,pattern))
{
for(int i=0; i<what.size(); i++)
cout<<"str :"<<what[i].str()<<endl;
}
⑦ 如何使用正則表達式匹配C語言的變數名定義規則
需要使用一個字元串作為c語言中的變數名,這個字元森肆串歲轎必須滿足下面的要求:
1.只包含數字,ASCII字母,下劃線
2.以字母乎春肆或者下劃線開頭