RegExp正則表達式基礎(chǔ)語法示例教程
簡介
在編寫處理字符串的程序或網(wǎng)頁時,經(jīng)常會有查找符合某些復(fù)雜規(guī)則的字符串的需要。正則表達式就是用于描述這些規(guī)則的工具。換句話說,正則表達式就是記錄文本規(guī)則的代碼。
很可能你使用過Windows/Dos下用于文件查找的通配符(wildcard),也就是*和?。如果你想查找某個目錄下的所有的Word文檔的話,你會搜索*.doc。在這里,*會被解釋成任意的字符串。和通配符類似,正則表達式也是用來進行文本匹配的工具,只不過比起通配符,它能更精確地描述你的需求——當(dāng)然,代價就是更復(fù)雜。
假設(shè)你在一篇英文小說里查找 hi,你可以使用正則表達式 hi。
這幾乎是最簡單的正則表達式了,它可以精確匹配這樣的字符串:由兩個字符組成,前一個字符是 h,后一個是 i。通常,處理正則表達式的工具會提供一個忽略大小寫的選項,如果選中了這個選項,它可以匹配 hi,HI,Hi,hI 這四種情況中的任意一種。
不幸的是,很多單詞里包含hi這兩個連續(xù)的字符,比如 him,history,high 等等。用 hi來查找的話,這里邊的 hi 也會被找出來。如果要精確地查找 hi 這個單詞的話,我們應(yīng)該使用\bhi\b。
\b 是正則表達式規(guī)定的一個特殊代碼(將其稱之為 元字符),代表著單詞的開頭或結(jié)尾,也就是單詞的分界處。雖然通常英文的單詞是由空格,標點符號或者換行來分隔的,但是\b并不匹配這些單詞分隔字符中的任何一個,它只匹配一個位置。
假如你要找的是hi后面不遠處跟著一個Lucy,你應(yīng)該用\bhi\b.*\bLucy\b。
這里,.是另一個元字符,匹配除了換行符以外的任意字符。* 同樣是元字符,不過它代表的不是字符,也不是位置,而是數(shù)量——它指定* 前邊的內(nèi)容可以連續(xù)重復(fù)使用任意次以使整個表達式得到匹配。
因此,.*連在一起就意味著任意數(shù)量的不包含換行的字符?,F(xiàn)在 \bhi\b.*\bLucy\b 的意思就很明顯了:先是一個單詞 hi,然后是任意個任意字符(但不能是換行),最后是 Lucy 這個單詞。
如果同時使用其它元字符,我們就能構(gòu)造出功能更強大的正則表達式。比如下面這個例子:
0\d\d-\d\d\d\d\d\d\d\d匹配這樣的字符串:以 0 開頭,然后是兩個數(shù)字,然后是一個連字號“-”,最后是8個數(shù)字(也就是中國的電話號碼。當(dāng)然,這個例子只能匹配區(qū)號為3位的情形)。
這里的\d是個新的元字符,匹配一位數(shù)字(0,或1,或2,或……)。- 不是元字符,只匹配它本身——連字符(或者減號,或者中橫線,或者隨你怎么稱呼它)。
為了避免那么多煩人的重復(fù),我們也可以這樣寫這個表達式:0\d{2}-\d{8}。這里\d后面的{2}({8})的意思是前面\d必須連續(xù)重復(fù)匹配 2 次(8次)。
總的來說,正則表達式一種特殊的編程語言,專門用來匹配一些特定的字符串。正則表達式一般不會單獨使用,通常會結(jié)合具體的編程語言(例如 C++、Python、Perl等)或者工具(vim等)使用。
在線工具
正則表達式本身比較復(fù)雜,可以借助一些工具來驗證所寫的正則表達式是否符合預(yù)期。
元字符
基本元字符
| Metacharacter | Descriptions | Examples |
|---|---|---|
| \ | 轉(zhuǎn)義字符,使后面的字符失去特殊含義或者標記為特殊字符 | \. 匹配實際的點號而不是任意字符,\n 匹配一個換行符 |
| ^ | 匹配字符串的開始位置 | ^abc 匹配以 abc 開頭的字符串 |
| $ | 匹配字符串的結(jié)束位置 | xyz$ 匹配以 “xyz” 結(jié)尾的字符串 |
| . | 匹配除換行符(\n)外的任意單個字符 | a.b 匹配 “aab”, “a1b”, “a b” 等 |
| * | 匹配前面的子表達式零次或多次 | zo* 能匹配 “z” 以及 “zoo” |
| + | 匹配前面的子表達式 1 次或多次 | zo+ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z” |
| ? | 匹配前面的子表達式零次或一次 | do(es)? 可以匹配 “do” 或 “does” |
| {n} | n 是一個非負整數(shù)。匹配確定的 n 次 | o{2} 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的兩個 o |
| {n,} | n 是一個非負整數(shù)。至少匹配n 次 | o{2,} 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o |
| {n,m} | m 和 n 均為非負整數(shù),其中n <= m。最少匹配 n 次且最多匹配 m 次 | o{1,3} 匹配 “fooooood” 中的前三個 o |
| x|y | 匹配 x 或 y | z|food 能匹配 “z” 或 “food” |
| [xyz] | 字符集合。匹配所包含的任意一個字符 | [abc] 可以匹配 “plain” 中的 ‘a’。 |
| [^xyz] | 負值字符集合。匹配未包含的任意字符 | [^abc] 可以匹配 “plain” 中的’p’、‘l’、‘i’、‘n’ |
| [a-z] | 字符范圍。匹配指定范圍內(nèi)的任意字符 | [a-z] 可以匹配 ‘a’ 到 ‘z’ 范圍內(nèi)的任意小寫字母字符 |
| [^a-z] | 負值字符范圍。匹配任何不在指定范圍內(nèi)的任意字符 | [^a-z] 可以匹配任何不在 ‘a’ 到 ‘z’ 范圍內(nèi)的任意字符 |
| \b | 匹配一個單詞邊界,也就是指單詞和空格間的位置 | er\b 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’ |
| \B | 匹配非單詞邊界 | er\B 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’ |
| \cx | 匹配由 x 指明的控制字符,x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個原義的 ‘c’ 字符 | \cM 匹配一個 Control-M 或回車符 |
| \d | 匹配一個數(shù)字字符 | 等價于 [0-9] |
| \D | 匹配一個非數(shù)字字符 | 等價于 [^0-9] |
| \f | 匹配一個換頁符 | 等價于 \x0c 和 \cL |
| \n | 匹配一個換行符 | 等價于 \x0a 和 \cJ |
| \r | 匹配一個回車符 | 等價于 \x0d 和 \cM |
| \s | 匹配任何空白字符,包括空格、制表符、換頁符等等 | 等價于 [ \f\n\r\t\v] |
| \S | 匹配任何非空白字符 | 等價于 [^ \f\n\r\t\v] |
| \t | 匹配一個制表符 | 等價于 \x09 和 \cI |
| \v | 匹配一個垂直制表符 | 等價于 \x0b 和 \cK |
| \w | 匹配字母、數(shù)字、下劃線 | 等價于 [A-Za-z0-9_] |
| \W | 匹配非字母、數(shù)字、下劃線 | 等價于 [^A-Za-z0-9_] |
分組與引用
直接在字符后面加上限定符,就可以實現(xiàn)重復(fù)單個字符。如果想要重復(fù)多個字符,比如重復(fù) ab,可以使用小括號來指定子表達式(也叫做分組),然后指定這個子表達式的重復(fù)次數(shù)。
例如,(ab)+ 可以匹配 “ab”、“abab”、“ababab” 等,但不能匹配 “a” 或 “b”。
- 捕獲分組
正則表達式中有幾種不同類型的分組,捕獲分組是最常見的分組形式,它會捕獲匹配的內(nèi)容并分配一個編號(從 1 開始)。后續(xù)可以基于編號訪問分組中的內(nèi)容。
示例:
(\d{4})-(\d{2})-(\d{2}) # 匹配日期格式 YYYY-MM-DD
這個表達式會創(chuàng)建3個分組:① 4位數(shù)字的年份;② 2位數(shù)字的月份;③ 2位數(shù)字的日期
- 分組引用
分組最強大的功能之一是可以在正則表達式內(nèi)部或外部引用已匹配的內(nèi)容。
在正則表達式內(nèi)部引用前面的分組,使用 \num,其中 num 是分組索引。
(\w+) \1 # 匹配重復(fù)的單詞,如 "hello hello"
這個 pattern 會匹配兩個相同的單詞,中間用空格分隔,其中 \1 就是對分組的引用。
- 非捕獲分組
使用 (?:pattern) 語法,表示只分組但不捕獲。
例如,(?:Mr|Ms|Mrs)\. (\w+) 表示匹配 “Mr. Smith” 但只捕獲 “Smith”。
- 命名分組與引用
在一些高級語言中,還可以為分組指定名稱,提高可讀性(不同語言語法可能不同)。
例如,在 Python 中對分組進行命令的方法如下:
### Named Capturing Group
(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})
### Reference
(?P<word>\w+) (?P=word)
運算符優(yōu)先級
正則表達式從左到右進行計算,并遵循優(yōu)先級順序,這與算術(shù)表達式非常類似。
相同優(yōu)先級的從左到右進行運算,不同優(yōu)先級的運算先高后低。
正則表達式中,各種運算符的優(yōu)先級順序如下:
| 優(yōu)先級 | 運算符 | 描述 |
|---|---|---|
| 1 | \ | 轉(zhuǎn)義符 |
| 2 | ()、[] | 圓括號和方括號 |
| 3 | *、 +、 ?、 {n}、{n,}、{n,m} | 限定符 |
| 4 | ^、$、\任何元字符、任何字符 | 定位點和序列(即:位置和順序) |
| 5 | | | "或"操作 |
貪婪模式
當(dāng)正則表達式中包含能接受重復(fù)的限定符時,通常的行為是(在使整個表達式能得到匹配的前提下)匹配盡可能多的字符。以表達式a.*b 為例,它將會匹配最長的以a開始,以b結(jié)束的字符串。如果用它來搜索aabab的話,它會匹配整個字符串a(chǎn)abab。這被稱為貪婪匹配。
有時,我們更需要懶惰匹配,也就是匹配盡可能少的字符。前面給出的限定符都可以被轉(zhuǎn)化為懶惰匹配模式,只要在它后面加上一個?。
這樣.*?就意味著匹配任意數(shù)量的重復(fù),但是在能使整個匹配成功的前提下使用最少的重復(fù)
a.*?b 匹配最短的,以a開始,以b結(jié)束的字符串。如果把它應(yīng)用于 aabab 的話,它會匹配 aab(第一到第三個字符)和ab(第四到第五個字符)。
為什么第一個匹配是aab(第一到第三個字符)而不是ab(第二到第三個字符)?簡單地說,因為正則表達式有另一條規(guī)則,比懶惰/貪婪規(guī)則的優(yōu)先級更高:最先開始的匹配擁有最高的優(yōu)先權(quán)。
對于其他的的重復(fù)限定符,都支持使用 ? 進入懶惰模式:

總結(jié)
到此這篇關(guān)于RegExp正則表達式基礎(chǔ)語法的文章就介紹到這了,更多相關(guān)RegExp正則表達式語法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python中使用正則表達式將所有符合條件的字段全部提取出來
這篇文章主要介紹了python中使用正則表達式將所有符合條件的字段全部提取出來,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08

