描述
QRegExp 類使用正則表達式提供模式匹配。
正則表達式或“正則表達式”是一種用于匹配文本中子字符串的模式。這在許多情況下都很有用,例如,
- 驗證
正則表達式可以測試子字符串是否滿足某些條件,例如是整數或不包含空格。 - 搜索
正則表達式提供了比簡單的子字符串匹配更強大的模式匹配,例如,匹配一個單詞 mail、letter 或 correspondence,但沒有一個單詞 email、mailman、mailer、letterbox 等。 - 搜索和替換
正則表達式可以用不同的子字符串替換子字符串的所有匹配項,例如,將所有出現的 & 替換為 &,除非 & 后面已經跟著 amp;。 - 字符串拆分
正則表達式可用于標識字符串應拆分的位置,例如拆分制表符分隔的字符串。
介紹
正則表達式由表達式、****量詞和斷言構建而成。最簡單的表達式是一個字符,例如 x 或 5。表達式也可以是用方括號括起來的一組字符。[ABCD] 將匹配 A 或 B 或 C 或 D。我們可以將這個表達式寫成 [A-D],并且與英語字母表中任何大寫字母匹配的表達式都寫成 [A-Z]。
量詞指定必須匹配的表達式的出現次數。x{1,1} 表示匹配 1 且僅匹配一個 x。x{1,5} 表示匹配包含至少一個 x 但不超過 5 個的 x 字符串行。
請注意,通常不能使用正則表達式來檢查平衡的括號或標記。例如,如果標簽沒有嵌套,則可以編寫正則表達式以匹配開始的 html 及其結束鍵,但如果標記是嵌套的,則相同的正則表達式將匹配具有錯誤結束符的開始標記。對于粗體的片段,第一個將與第一個匹配,這是不正確的。但是,可以編寫一個正確匹配嵌套括號或標記的正則表達式,但前提是嵌套級別的數量是固定的和已知的。如果嵌套級別的數量不是固定的和已知的,則不可能編寫不會失敗的正則表達式。
假設我們希望正則表達式匹配 0 到 99 范圍內的整數。至少需要一位數字,因此我們從表達式 [0-9]{1,1} 開始,它與一位數字正好匹配一次。此正則表達式匹配 0 到 9 范圍內的整數。若要匹配最大 99 的整數,請將最大出現次數增加到 2,因此正則表達式變為 [0-9]{1,2}。此正則表達式滿足匹配 0 到 99 之間的整數的原始要求,但它也將匹配出現在字符串中間的整數。如果我們希望匹配的整數是整個字符串,我們必須使用錨斷言 ^(插入符號)和 $(美元)。當 ^ 是正則表達式中的第一個字符時,這意味著正則表達式必須從字符串的開頭開始匹配。當 $ 是正則表達式的最后一個字符時,這意味著正則表達式必須與字符串的末尾匹配。正則表達式變為 ^[0-9]{1,2}$
。請注意,斷言(例如 ^ 和 $)不匹配字符串中的字符,而是匹配位置。
如果您看過其他地方描述的正則表達式,它們可能看起來與此處顯示的正則表達式不同。這是因為某些字符集和某些量詞非常常見,以至于它們被賦予了特殊的符號來表示它們。[0-9] 可以替換為符號 \d。正好匹配一個出現次數的量詞 {1,1} 可以替換為表達式本身,即 x{1,1} 與 x 相同。所以我們的 0 到 99 匹配器可以寫成 ^\d{1,2}KaTeX parse error: Undefined control sequence: \d at position 10: 。它也可以寫成 ^\?d?\d{0,1},即從字符串的開頭開始,匹配一個數字,緊接著是 0 或 1 位數字。在實踐中,它將被寫成 ^\d\d?KaTeX parse error: Undefined control sequence: \d at position 48: …達式成為可選的。正則表達式 ^\?d?\d? 表示從字符串的開頭開始,匹配一個數字,緊接著是 0 或 1 個數字,緊接著是字符串的末尾。
要編寫與“mail”或“letter”或“correspondence”之一匹配但不匹配包含這些單詞的單詞(例如“email”、“mailman”、“mailer”和“letterbox”)的正則表達式,請從匹配“mail”的正則表達式開始。完全表示時,正則表達式是 m{1,1}a{1,1}i{1,1}l{1,1},但是由于字符表達式由 {1,1} 自動量化,因此我們可以將正則表達式簡化為郵件,即“m”后跟“a”,后跟“i”,后跟“l”。現在我們可以使用豎線 |,這意味著 or,包括其他兩個單詞,因此我們匹配三個單詞中的任何一個的正則表達式變為 mail|letter|correspondence。匹配“郵件”或“信件”或“通信”。雖然此正則表達式將匹配我們想要匹配的三個單詞之一,但它也將匹配我們不想匹配的單詞,例如“電子郵件”。為了防止正則表達式匹配不需要的單詞,我們必須告訴它在單詞邊界處開始和結束匹配。首先,我們將正則表達式括在括號中,(mail|letter|correspondence)。括號將表達式組合在一起,它們標識了我們希望捕獲的正則表達式的一部分。將表達式括在括號中允許我們將其用作更復雜的正則表達式中的組件。它還允許我們檢查這三個單詞中的哪一個是實際匹配的。為了強制匹配在單詞邊界上開始和結束,我們將正則表達式括在 \b 單詞邊界斷言中:\b(mail|letter|correspondence)\b。現在正則表達式的意思是:匹配一個單詞邊界,后跟括號中的正則表達式,后跟一個單詞邊界。\b 斷言匹配正則表達式中的位置,而不是字符。單詞邊界是任何非單詞字符,例如空格、換行符或字符串的開頭或結尾。
如果我們想用 HTML 實體 && 替換 & 字符,要匹配的正則表達式就是 &。但此正則表達式還將匹配已轉換為 HTML 實體的 & 符號。我們只想替換尚未跟在 amp; 后面的 & 符號。為此,我們需要否定的前瞻性斷言,(?!__).然后,正則表達式可以寫成 &(?!amp;),即匹配一個不跟 amp; 的 &。
如果我們想計算字符串中所有出現的“Eric”和“Eirik”,兩個有效的解決方案是 \b(Eric|Eirik)\b 和 \bEi?ri[ck]\b.需要單詞邊界斷言“\b”來避免匹配包含任一名稱的單詞,例如“Ericsson”。請注意,第二個正則表達式匹配的拼寫比我們想要的要多:“Eric”、“Erik”、“Eiric”和“Eirik”。
符號 | 意思 |
---|---|
c | 一個字符代表它自己,c匹配字符c,除非這個 字符有特殊含義 |
\c | 一個反斜杠加一個字符,匹配字符本身,例外: ^:匹配字符串開頭的文字插入符 |
\a | 匹配一個響鈴符 |
\f | 匹配一個分頁符 |
\n | 匹配一個換行符 |
\r | 匹配一個回車符 |
\t | 匹配一個水平制表符 |
\v | 匹配一個垂直制表符 |
\xhhh | 匹配與十六進制數hhhh(在0x0000和OxFFF之間)對應的Unicode字符 |
\0ooo | 匹配總數為o00(介于0和0377之間)的ASCI/拉丁字符。 |
. | 匹配任意字符 |
\d | 匹配一個數字 |
\D | 匹配一個非數字 |
\s | 匹配一個空格 |
\S | 匹配一個非空格 |
\w | 匹配一個單詞 |
\W | 匹配一個非單詞 |
字符集
方括號表示與方括號中包含的任何字符匹配。上述字符集縮寫可以出現在方括號中的字符集中。除字符集縮寫和以下兩個例外情況外,字符在方括號中沒有特殊含義。
字符 | 含義 |
---|---|
^ | 如果字符集作為第一個字符出現(即緊接在左方括號之后),則插入符號將否定該字符集。[abc] 匹配 ‘a’ 或 ‘b’ 或 ‘c’,但 [^abc] 匹配 ‘a’ 或 ‘b’ 或 ‘c’ 以外的任何內容。 |
- | 破折號表示字符范圍。[W-Z] 匹配“W”或“X”或“Y”或“Z”。 |
使用預定義的字符集縮寫比跨平臺和語言使用字符范圍更具可移植性。例如,[0-9] 匹配西方字母表中的數字,但 \d 匹配任何字母表中的數字。
注意:在其他正則表達式文檔中,字符集通常稱為“字符類”。
量詞
默認情況下,表達式由{1,1}自動量化,即它應該只出現一次。在下面的列表中,E代表表達式。表達式是一個字符,或者是一組字符的縮寫,或者是方括號中的一組字符,或者是圓括號中的表達式。
量詞 | 含義 |
---|---|
E? | 這個量詞表示E可以出現零次或一次。這意味著前面的表達式是可選的,因為它會匹配無論是否找到該表達式。E? 和 E{0,1} 是等價的。例如,dents? 匹配 ‘dent’ 或 ‘dents’。這個量詞用于正則表達式中,用于指定某個模式的可選性。在上述例子中,“dents?” 將匹配 ‘dent’ 或 ‘dents’ 這兩個單詞,其中 “s” 的出現是可選的。 |
E+ | 匹配一個或多個出現的E.E+與E{1, }相同。例如,0+匹配“0”“00”“000”等 |
E* | 匹配零次或多次出現的 E。它與 E{0,} 相同。* 量詞經常在錯誤中使用,其中應該使用 +。例如,如果在表達式中使用 \s*$ 來匹配以空格結尾的字符串,它將匹配每個字符串,因為 \s*$ 表示匹配零個或多個空格,后跟字符串末尾。匹配至少具有一個尾部空格字符的字符串的正確正則表達式是 \s+$。 |
E{n} | 匹配出現n次E的字符 |
E{n,} | 至少出現n次 |
E{,m} | 最多出現m次 |
E{n.m} | 至少出現n次,最多出現m次 |
斷言
斷言在regexp中出現的地方對文本做出一些聲明,但是它們不匹配任何字符。在下面的列表中,E代表任何表達式。
斷言 | 含義 |
---|---|
^ | 插入符號表示字符串的開頭。如果你想匹配一個文本 ^,你必須通過寫 \^ 來轉義它。例如,^#include 將僅匹配以字符“#include”開頭的字符串。(當插入符號是字符集的第一個字符時,它具有特殊含義,請參閱字符集。 |
$ | KaTeX parse error: Undefined control sequence: \d at position 13: 表示字符串的末端。例如,\?d?\s* 將匹配以數字結尾的字符串(可選),后跟空格。如果你想匹配一個文本 $,你必須通過寫入 \$ 來轉義它。 |
\b | 一個詞的邊界。例如,正則表達式 \bOK\b 表示緊跟在單詞邊界(例如字符串或空格的開頭)之后的字母“O”,然后是緊接在另一個單詞邊界(例如字符串末尾或空格)之前的字母“K”。但請注意,該斷言實際上并不匹配任何空格,因此如果我們編寫 (\bOK\b) 并且我們有一個匹配項,即使字符串是“It’s OK now”,它也只會包含“OK”。 |
\B | 非單詞邊界。如果 \b 為 false,則此斷言為 true。例如,如果我們在“Left on”中搜索 \Bon\B,則匹配將失敗(空格和字符串末尾不是非單詞邊界),但它會在“tonne”中匹配。 |
(?=E) | 正向先行斷言(Positive lookahead)是一種正則表達式中的斷言語法,如果在當前位置匹配成功,則斷言為真。例如,const(?=\s+char) 表達式匹配 ‘const’,但僅當其后緊跟著 ‘char’ 時才為真,比如在 ‘static const char *’ 中。(與 const\s+char 進行對比,后者匹配 ‘static const char *’ 的整個字符串)。這種斷言用于對某些模式進行前瞻性判斷,以確保后續的匹配符合預期。 |
?!E | 負向先行斷言(Negative lookahead)是正則表達式中的一種斷言語法,如果在當前位置匹配失敗,則斷言為真。例如,const(?!\s+char) 表達式匹配 ‘const’,但當其后緊跟著 ‘char’ 時,斷言會失敗,即不匹配。這意味著該表達式可以用于排除某些特定的模式,確保后續的匹配不包含指定的內容。在給定的例子中,‘const’ 只有在不跟隨 ‘char’ 的情況下才會匹配成功。 |
通配符匹配
大多數命令shell(如bash或cmd.exe)都支持“文件全局搜索”,即通過使用通配符來識別一組文件的能力。函數的作用是:在regexp和通配符模式之間進行切換。通配符匹配比完整的regexp簡單得多,并且只有四個特性:
通配符 | 含義 |
---|---|
c | 除了下面提到的字符外,任何字符都代表自己。因此c與字符c匹配。 |
? | 匹配任何單個字符。它與完全正則表達式中的 . 相同。 |
* | 匹配零個或多個任何字符。它與完整正則表達式中的 .* 相同。 |
[…] | 字符集可以用方括號表示,與完整的正則表達式類似。在字符集內部,就像在外部一樣,反斜杠沒有特殊含義。這意味著在字符集中使用反斜杠不會具有轉義或特殊的含義。例如,[abc] 表示匹配字符 ‘a’、‘b’ 或 ‘c’ 中的任意一個。在字符集內部,元字符(如點號、星號等)通常被當作普通字符對待,而不是其正則表達式的特殊功能。然而,需要注意的是,方括號內的連字符(-)有時候會表示字符范圍,例如 [a-z] 表示匹配從小寫字母’a’到’z’之間的任意一個字符。 |