需求:從字符串 "[]abcd[12345]ddx" 中提取 "abcd[" 與其後第一個 "]" 之間的內容 "12345"。MySQL 無 indexOf,但提供 LOCATE、SUBSTRING 組合實現。
DELIMITER $$
CREATE PROCEDURE `sp_str_between`(
IN p_str VARCHAR(500), -- 原始字符串
IN p_begin_str VARCHAR(100), -- 起始標記
IN p_end_str VARCHAR(100), -- 結束標記
OUT p_result VARCHAR(500) -- 提取結果
)
BEGIN
DECLARE v_start_pos INT DEFAULT 0;
DECLARE v_end_pos INT DEFAULT 0;
-- 1. 找到起始標記結束位置
SELECT LOCATE(p_begin_str, p_str) + CHAR_LENGTH(p_begin_str) INTO v_start_pos;
-- 2. 從起始位置向後找結束標記
SELECT LOCATE(p_end_str, p_str, v_start_pos) INTO v_end_pos;
-- 3. 截取中間內容
IF v_start_pos > 0 AND v_end_pos > 0 THEN
SELECT SUBSTRING(p_str, v_start_pos, v_end_pos - v_start_pos) INTO p_result;
ELSE
SET p_result = NULL;
END IF;
END $$
DELIMITER ;
CALL sp_str_between('[]abcd[12345]aa[]ss', 'abcd[', ']', @result);
SELECT @result; -- 12345
CALL sp_str_between('[]abcd[sdww]aa[]ss', 'abcd[', ']', @result);
SELECT @result; -- sdww
SELECT SUBSTRING(
']abcd[12345]111[]',
LOCATE('abcd[', ']abcd[12345]111[]') + CHAR_LENGTH('abcd['),
LOCATE(']', ']abcd[12345]111[]', CHAR_LENGTH('abcd[')) -
(LOCATE('abcd[', ']abcd[12345]111[]') + CHAR_LENGTH('abcd['))
) AS extracted;
-- 結果:12345
| 函數 | 語法 | 說明 |
|---|---|---|
| LOCATE | LOCATE(substr, str [, pos]) | 返回 substr 在 str 中首次出現位置 (從 1 起);pos 指定起始搜索位置。未找到返回 0。 |
| CHAR_LENGTH | CHAR_LENGTH(str) | 返回字符數(多字節字符計 1),而非字節數。 |
| SUBSTRING | SUBSTRING(str, pos, len) | 從 pos 位置截取 len 個字符。pos 從 1 開始。 |
SUBSTRING_INDEX 配合
SELECT REGEXP_SUBSTR('[]abcd[12345]ddx', '(?<=abcd\\[)[^\\]]+');
-- 12345
-- 正則解析:(?<=abcd\\[) 正向後顧斷言,匹配 abcd[ 後的位置;[^\\]]+ 匹配非 ] 字符一個或多個