文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
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 patexpr NOT RLIKE pat

    這與 NOT (expr REGEXP pat) 相同。

  • expr REGEXP patexpr 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 |
    +------------------------------------------------------------------+

    可以使用 ci 字元指定 match_type,以覆寫預設的大小寫敏感度。例外情況:如果任一引數是二進位字串,則會以大小寫敏感的方式將引數視為二進位字串處理,即使 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 程式庫所支援的完整正規表示式語法的資訊,請造訪Unicode 國際元件網站

  • ^

    比對字串的開頭。

    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} 精確比對 an 個執行個體。a{n,} 比對 an 個或更多個執行個體。a{m,n} 比對 amn 個執行個體,包括 mn。如果給定 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 空格、Tab、換行符號和歸位
    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 系統變數。由於此限制表示為步驟數,因此它僅會間接影響執行時間。通常,它大約為毫秒級。