文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


14.8.2 正規表達式

表格 14.14 正規表達式函數與運算子

名稱 描述
NOT REGEXP REGEXP 的否定
REGEXP 字串是否符合正規表達式
REGEXP_INSTR() 符合正規表達式的子字串起始索引
REGEXP_LIKE() 字串是否符合正規表達式
REGEXP_REPLACE() 取代符合正規表達式的子字串
REGEXP_SUBSTR() 傳回符合正規表達式的子字串
RLIKE 字串是否符合正規表達式

正規表達式是一種指定複雜搜尋模式的強大方式。本節討論可用於正規表達式比對的函數和運算子,並舉例說明可用於正規表達式操作的一些特殊字元和結構。另請參閱 第 5.3.4.7 節「模式比對」

MySQL 使用國際組件 Unicode (ICU) 實作正規表達式支援,它提供完整的 Unicode 支援並且是多位元組安全的。

使用二進位字串搭配任何 MySQL 正規表達式函數會遭到拒絕,並顯示 ER_CHARACTER_SET_MISMATCH 錯誤。

正規表達式函數與運算子描述

  • expr NOT REGEXP pat, expr NOT RLIKE pat

    這與 NOT (expr REGEXP pat) 相同。

  • expr REGEXP pat, expr RLIKE pat

    如果字串 expr 符合模式 pat 指定的正規表達式,則傳回 1,否則傳回 0。如果 exprpatNULL,則傳回值為 NULL

    REGEXPRLIKEREGEXP_LIKE() 的同義詞。

    如需關於比對如何發生的其他資訊,請參閱 REGEXP_LIKE() 的描述。

    mysql> SELECT 'Michael!' REGEXP '.*';
    +------------------------+
    | 'Michael!' REGEXP '.*' |
    +------------------------+
    |                      1 |
    +------------------------+
    mysql> SELECT 'new*\n*line' REGEXP 'new\\*.\\*line';
    +---------------------------------------+
    | 'new*\n*line' REGEXP 'new\\*.\\*line' |
    +---------------------------------------+
    |                                     0 |
    +---------------------------------------+
    mysql> SELECT 'a' REGEXP '^[a-d]';
    +---------------------+
    | 'a' REGEXP '^[a-d]' |
    +---------------------+
    |                   1 |
    +---------------------+
  • REGEXP_INSTR(expr, pat[, pos[, occurrence[, return_option[, match_type]]]])

    傳回字串 expr 中符合模式 pat 指定之正規表達式的子字串的起始索引,如果沒有比對則傳回 0。如果 exprpatNULL,則傳回值為 NULL。字元索引從 1 開始。

    REGEXP_INSTR() 接受這些選用引數

    • pos:在 expr 中開始搜尋的位置。如果省略,則預設值為 1。

    • occurrence:要搜尋的符合項次數。如果省略,則預設值為 1。

    • return_option:要傳回的位置類型。如果此值為 0,則 REGEXP_INSTR() 會傳回符合子字串的第一個字元的位置。如果此值為 1,則 REGEXP_INSTR() 會傳回符合子字串後面的位置。如果省略,則預設值為 0。

    • match_type:指定如何執行比對的字串。其意義與 REGEXP_LIKE() 的描述相同。

    如需關於比對如何發生的其他資訊,請參閱 REGEXP_LIKE() 的描述。

    mysql> SELECT REGEXP_INSTR('dog cat dog', 'dog');
    +------------------------------------+
    | REGEXP_INSTR('dog cat dog', 'dog') |
    +------------------------------------+
    |                                  1 |
    +------------------------------------+
    mysql> SELECT REGEXP_INSTR('dog cat dog', 'dog', 2);
    +---------------------------------------+
    | REGEXP_INSTR('dog cat dog', 'dog', 2) |
    +---------------------------------------+
    |                                     9 |
    +---------------------------------------+
    mysql> SELECT REGEXP_INSTR('aa aaa aaaa', 'a{2}');
    +-------------------------------------+
    | REGEXP_INSTR('aa aaa aaaa', 'a{2}') |
    +-------------------------------------+
    |                                   1 |
    +-------------------------------------+
    mysql> SELECT REGEXP_INSTR('aa aaa aaaa', 'a{4}');
    +-------------------------------------+
    | REGEXP_INSTR('aa aaa aaaa', 'a{4}') |
    +-------------------------------------+
    |                                   8 |
    +-------------------------------------+
  • REGEXP_LIKE(expr, pat[, match_type])

    如果字串 expr 符合模式 pat 指定的正規表達式,則傳回 1,否則傳回 0。如果 exprpatNULL,則傳回值為 NULL

    模式可以是擴充正規表達式,其語法在正規表達式語法中討論。模式不需要是常值字串。例如,它可以指定為字串表達式或表格欄。

    選用引數 match_type 是字串,可以包含任何或所有下列字元,指定如何執行比對

    • c:區分大小寫的比對。

    • i:不區分大小寫的比對。

    • m:多行模式。辨識字串中的行終止符。預設行為是僅在字串表達式的開頭和結尾比對行終止符。

    • n. 字元會匹配行終止符。預設情況下,. 的匹配會在行尾停止。

    • u:僅限 Unix 的行尾。只有換行字元會被 .^$ 匹配運算子識別為行尾。

    如果在 match_type 中指定了相互矛盾的選項字元,則最右邊的優先。

    預設情況下,在決定字元的類型和執行比較時,正規表示式操作會使用 exprpat 引數的字元集和定序。如果引數具有不同的字元集或定序,則會套用強制轉換規則,如第 12.8.4 節「運算式中的定序強制轉換」中所述。引數可以使用明確的定序指示符指定,以變更比較行為。

    mysql> SELECT REGEXP_LIKE('CamelCase', 'CAMELCASE');
    +---------------------------------------+
    | REGEXP_LIKE('CamelCase', 'CAMELCASE') |
    +---------------------------------------+
    |                                     1 |
    +---------------------------------------+
    mysql> SELECT REGEXP_LIKE('CamelCase', 'CAMELCASE' COLLATE utf8mb4_0900_as_cs);
    +------------------------------------------------------------------+
    | REGEXP_LIKE('CamelCase', 'CAMELCASE' COLLATE utf8mb4_0900_as_cs) |
    +------------------------------------------------------------------+
    |                                                                0 |
    +------------------------------------------------------------------+

    match_type 可以指定 ci 字元來覆寫預設的大小寫敏感性。例外情況:如果任一引數是二進位字串,則會以大小寫敏感的方式將引數視為二進位字串處理,即使 match_type 包含 i 字元也一樣。

    注意

    MySQL 在字串中使用 C 跳脫語法 (例如,\n 代表換行字元)。如果您希望 exprpat 引數包含一個字面上的 \,則必須將其加倍。(除非啟用了 NO_BACKSLASH_ESCAPES SQL 模式,在這種情況下,不會使用跳脫字元。)

    mysql> SELECT REGEXP_LIKE('Michael!', '.*');
    +-------------------------------+
    | REGEXP_LIKE('Michael!', '.*') |
    +-------------------------------+
    |                             1 |
    +-------------------------------+
    mysql> SELECT REGEXP_LIKE('new*\n*line', 'new\\*.\\*line');
    +----------------------------------------------+
    | REGEXP_LIKE('new*\n*line', 'new\\*.\\*line') |
    +----------------------------------------------+
    |                                            0 |
    +----------------------------------------------+
    mysql> SELECT REGEXP_LIKE('a', '^[a-d]');
    +----------------------------+
    | REGEXP_LIKE('a', '^[a-d]') |
    +----------------------------+
    |                          1 |
    +----------------------------+
    mysql> SELECT REGEXP_LIKE('abc', 'ABC');
    +---------------------------+
    | REGEXP_LIKE('abc', 'ABC') |
    +---------------------------+
    |                         1 |
    +---------------------------+
    mysql> SELECT REGEXP_LIKE('abc', 'ABC', 'c');
    +--------------------------------+
    | REGEXP_LIKE('abc', 'ABC', 'c') |
    +--------------------------------+
    |                              0 |
    +--------------------------------+
  • REGEXP_REPLACE(expr, pat, repl[, pos[, occurrence[, match_type]]])

    將字串 expr 中符合模式 pat 所指定正規表示式的出現次數,取代為取代字串 repl,並傳回產生的字串。如果 exprpatreplNULL,則傳回值為 NULL

    REGEXP_REPLACE() 接受以下選用引數

    • pos:在 expr 中開始搜尋的位置。如果省略,則預設值為 1。

    • occurrence:要取代的匹配項的第幾次出現。如果省略,則預設為 0 (表示「取代所有出現次數」)。

    • match_type:指定如何執行比對的字串。其意義與 REGEXP_LIKE() 的描述相同。

    此函數傳回的結果使用搜尋比對之運算式的字元集和定序。

    如需關於比對如何發生的其他資訊,請參閱 REGEXP_LIKE() 的描述。

    mysql> SELECT REGEXP_REPLACE('a b c', 'b', 'X');
    +-----------------------------------+
    | REGEXP_REPLACE('a b c', 'b', 'X') |
    +-----------------------------------+
    | a X c                             |
    +-----------------------------------+
    mysql> SELECT REGEXP_REPLACE('abc def ghi', '[a-z]+', 'X', 1, 3);
    +----------------------------------------------------+
    | REGEXP_REPLACE('abc def ghi', '[a-z]+', 'X', 1, 3) |
    +----------------------------------------------------+
    | abc def X                                          |
    +----------------------------------------------------+
  • REGEXP_SUBSTR(expr, pat[, pos[, occurrence[, match_type]]])

    傳回字串 expr 中符合模式 pat 所指定正規表示式的子字串,如果沒有匹配項則傳回 NULL。如果 exprpatNULL,則傳回值為 NULL

    REGEXP_SUBSTR() 接受以下選用引數

    • pos:在 expr 中開始搜尋的位置。如果省略,則預設值為 1。

    • occurrence:要搜尋的符合項次數。如果省略,則預設值為 1。

    • match_type:指定如何執行比對的字串。其意義與 REGEXP_LIKE() 的描述相同。

    此函數傳回的結果使用搜尋比對之運算式的字元集和定序。

    如需關於比對如何發生的其他資訊,請參閱 REGEXP_LIKE() 的描述。

    mysql> SELECT REGEXP_SUBSTR('abc def ghi', '[a-z]+');
    +----------------------------------------+
    | REGEXP_SUBSTR('abc def ghi', '[a-z]+') |
    +----------------------------------------+
    | abc                                    |
    +----------------------------------------+
    mysql> SELECT REGEXP_SUBSTR('abc def ghi', '[a-z]+', 1, 3);
    +----------------------------------------------+
    | REGEXP_SUBSTR('abc def ghi', '[a-z]+', 1, 3) |
    +----------------------------------------------+
    | ghi                                          |
    +----------------------------------------------+

正規表示式語法

正規表示式描述一組字串。最簡單的正規表示式是不包含任何特殊字元的正規表示式。例如,正規表示式 hello 會匹配 hello,而不會匹配其他字串。

非普通的正規表示式使用某些特殊建構,以便它們可以匹配多個字串。例如,正規表示式 hello|world 包含 | 交替運算子,並匹配 helloworld

舉一個更複雜的例子,正規表示式 B[an]*s 會匹配任何字串 BananasBaaaaasBs 以及任何其他以 B 開頭、以 s 結尾,並且中間包含任意數量的 an 字元的字串。

以下清單涵蓋了一些正規表示式中可使用的基本特殊字元和建構。如需有關用於實作正規表示式支援的 ICU 程式庫所支援的完整正規表示式語法的資訊,請造訪國際組件統一碼網站

  • ^

    匹配字串的開頭。

    mysql> SELECT REGEXP_LIKE('fo\nfo', '^fo$');                   -> 0
    mysql> SELECT REGEXP_LIKE('fofo', '^fo');                      -> 1
  • $

    匹配字串的結尾。

    mysql> SELECT REGEXP_LIKE('fo\no', '^fo\no$');                 -> 1
    mysql> SELECT REGEXP_LIKE('fo\no', '^fo$');                    -> 0
  • .

    匹配任何字元(包括歸位字元和換行字元,儘管若要在字串中間匹配這些字元,則必須提供 m (多行) 匹配控制字元或模式內的 (?m))。

    mysql> SELECT REGEXP_LIKE('fofo', '^f.*$');                    -> 1
    mysql> SELECT REGEXP_LIKE('fo\r\nfo', '^f.*$');                -> 0
    mysql> SELECT REGEXP_LIKE('fo\r\nfo', '^f.*$', 'm');           -> 1
    mysql> SELECT REGEXP_LIKE('fo\r\nfo', '(?m)^f.*$');           -> 1
  • a*

    匹配零或多個 a 字元的任何序列。

    mysql> SELECT REGEXP_LIKE('Ban', '^Ba*n');                     -> 1
    mysql> SELECT REGEXP_LIKE('Baaan', '^Ba*n');                   -> 1
    mysql> SELECT REGEXP_LIKE('Bn', '^Ba*n');                      -> 1
  • a+

    匹配一個或多個 a 字元的任何序列。

    mysql> SELECT REGEXP_LIKE('Ban', '^Ba+n');                     -> 1
    mysql> SELECT REGEXP_LIKE('Bn', '^Ba+n');                      -> 0
  • a?

    匹配零個或一個 a 字元。

    mysql> SELECT REGEXP_LIKE('Bn', '^Ba?n');                      -> 1
    mysql> SELECT REGEXP_LIKE('Ban', '^Ba?n');                     -> 1
    mysql> SELECT REGEXP_LIKE('Baan', '^Ba?n');                    -> 0
  • de|abc

    交替;匹配序列 deabc 中的任一項。

    mysql> SELECT REGEXP_LIKE('pi', 'pi|apa');                     -> 1
    mysql> SELECT REGEXP_LIKE('axe', 'pi|apa');                    -> 0
    mysql> SELECT REGEXP_LIKE('apa', 'pi|apa');                    -> 1
    mysql> SELECT REGEXP_LIKE('apa', '^(pi|apa)$');                -> 1
    mysql> SELECT REGEXP_LIKE('pi', '^(pi|apa)$');                 -> 1
    mysql> SELECT REGEXP_LIKE('pix', '^(pi|apa)$');                -> 0
  • (abc)*

    匹配序列 abc 的零或多個執行個體。

    mysql> SELECT REGEXP_LIKE('pi', '^(pi)*$');                    -> 1
    mysql> SELECT REGEXP_LIKE('pip', '^(pi)*$');                   -> 0
    mysql> SELECT REGEXP_LIKE('pipi', '^(pi)*$');                  -> 1
  • {1}, {2,3}

    重複;{n}{m,n} 符號提供了一種更通用的方式來編寫匹配模式先前原子 (或「片段」) 多次出現的正規表示式。mn 是整數。

    • a*

      可以寫成 a{0,}

    • a+

      可以寫成 a{1,}

    • a?

      可以寫成 a{0,1}

    更精確地說,a{n} 匹配正好 na 的執行個體。a{n,} 匹配 n 個或更多個 a 的執行個體。a{m,n} 匹配從 mn 個 (含) a 的執行個體。如果同時提供 mn,則 m 必須小於或等於 n

    mysql> SELECT REGEXP_LIKE('abcde', 'a[bcd]{2}e');              -> 0
    mysql> SELECT REGEXP_LIKE('abcde', 'a[bcd]{3}e');              -> 1
    mysql> SELECT REGEXP_LIKE('abcde', 'a[bcd]{1,10}e');           -> 1
  • [a-dX][^a-dX]

    匹配任何是 (或不是,如果使用 ^) abcdX 的字元。兩個其他字元之間的 - 字元形成一個範圍,該範圍會匹配從第一個字元到第二個字元的所有字元。例如,[0-9] 會匹配任何十進位數字。若要包含字面上的 ] 字元,它必須緊接在開頭方括號 [ 之後。若要包含字面上的 - 字元,則必須將其寫在最前面或最後面。在 [] 對內沒有定義特殊含義的任何字元只會匹配它自己。

    mysql> SELECT REGEXP_LIKE('aXbc', '[a-dXYZ]');                 -> 1
    mysql> SELECT REGEXP_LIKE('aXbc', '^[a-dXYZ]$');               -> 0
    mysql> SELECT REGEXP_LIKE('aXbc', '^[a-dXYZ]+$');              -> 1
    mysql> SELECT REGEXP_LIKE('aXbc', '^[^a-dXYZ]+$');             -> 0
    mysql> SELECT REGEXP_LIKE('gheis', '^[^a-dXYZ]+$');            -> 1
    mysql> SELECT REGEXP_LIKE('gheisa', '^[^a-dXYZ]+$');           -> 0
  • [=character_class=]

    在方括號運算式 (使用 [] 寫入) 中,[=character_class=] 代表一個等價類別。它會匹配具有相同定序值的所有字元 (包括它自己)。例如,如果 o(+) 是等價類別的成員,則 [[=o=]][[=(+)=]][o(+)] 全部都是同義的。等價類別不得用作範圍的端點。

  • [:character_class:]

    在方括號運算式 (使用 [] 寫入) 中,[:character_class:] 代表一個字元類別,該類別會匹配屬於該類別的所有字元。下表列出了標準類別名稱。這些名稱代表 ctype(3) 手冊頁中定義的字元類別。特定的地區設定可能會提供其他類別名稱。字元類別不得用作範圍的端點。

    字元類別名稱 含義
    alnum 字母數字字元
    alpha 字母字元
    blank 空白字元
    cntrl 控制字元
    digit 數字字元
    graph 圖形字元
    lower 小寫字母字元
    print 圖形或空格字元
    punct 標點符號字元
    space 空格、定位字元、換行符號和歸位字元
    upper 大寫字母字元
    xdigit 十六進位數字字元
    mysql> SELECT REGEXP_LIKE('justalnums', '[[:alnum:]]+');       -> 1
    mysql> SELECT REGEXP_LIKE('!!', '[[:alnum:]]+');               -> 0

若要在正規表示式中使用特殊字元的字面執行個體,請在其前面加上兩個反斜線 (\) 字元。MySQL 解析器會解譯其中一個反斜線,而正規表示式程式庫會解譯另一個反斜線。例如,若要匹配包含特殊 + 字元的字串 1+2,則下列正規表示式中只有最後一個是正確的

mysql> SELECT REGEXP_LIKE('1+2', '1+2');                       -> 0
mysql> SELECT REGEXP_LIKE('1+2', '1\+2');                      -> 0
mysql> SELECT REGEXP_LIKE('1+2', '1\\+2');                     -> 1

正規表示式資源控制

REGEXP_LIKE() 和類似的函數使用可透過設定系統變數來控制的資源

  • 匹配引擎會將記憶體用於其內部堆疊。若要控制堆疊的最大可用記憶體 (以位元組為單位),請設定 regexp_stack_limit 系統變數。

  • 匹配引擎會分步驟運作。若要控制引擎執行的最大步驟數 (並因此間接控制執行時間),請設定 regexp_time_limit 系統變數。由於此限制是以步驟數表示,因此它只會間接影響執行時間。通常,它大約是以毫秒為單位。