ดูเหมือนว่าไม่มีคำตอบใดในปัจจุบันที่จะลบช่องว่างได้ 100% จากจุดเริ่มต้นและจุดสิ้นสุดของสตริง
เป็นที่กล่าวถึงในบทความอื่น ๆ เริ่มต้นTRIM
เพียงเอาช่องว่าง - ไม่ได้แท็บ formfeeds ฯลฯ การรวมกันของTRIM
s ระบุตัวอักษรช่องว่างอื่น ๆ TRIM(BOTH '\r' FROM TRIM(BOTH '\n' FROM TRIM(BOTH '\f' FROM TRIM(BOTH '\t' FROM TRIM(txt)))))
ที่อาจจัดให้มีการปรับปรุงเช่น แต่ปัญหาเกี่ยวกับแนวทางนี้คือสามารถระบุได้เพียงอักขระเดียวสำหรับบางตัวTRIM
และอักขระเหล่านั้นจะถูกลบออกจากจุดเริ่มต้นและจุดสิ้นสุดเท่านั้น ดังนั้นหากสตริงที่ถูกตัดออกเป็นบางอย่างเช่น\t \t \t \t
(เช่นช่องว่างทางเลือกและอักขระแท็บ) TRIM
ก็จะต้องมีจำนวนมากขึ้น- และในกรณีทั่วไปสิ่งนี้อาจดำเนินต่อไปเรื่อย ๆ
สำหรับโซลูชันที่มีน้ำหนักเบาควรเขียน User Defined Function (UDF) อย่างง่ายเพื่อทำงานโดยการวนซ้ำอักขระที่จุดเริ่มต้นและจุดสิ้นสุดของสตริง แต่ฉันจะไม่ทำอย่างนั้น ... ในขณะที่ฉันได้เขียนตัวแทนที่นิพจน์ทั่วไปที่ค่อนข้างมีน้ำหนักมากซึ่งสามารถทำงานได้เช่นกันและอาจมีประโยชน์ด้วยเหตุผลอื่น ๆ ตามที่อธิบายไว้ในบล็อกโพสต์นี้
การสาธิต
Rextester ออนไลน์สาธิต โดยเฉพาะอย่างยิ่งแถวสุดท้ายแสดงวิธีการอื่นที่ล้มเหลว แต่วิธีการแสดงออกปกติประสบความสำเร็จ
ฟังก์ชัน :
DROP FUNCTION IF EXISTS reg_replace;
CREATE FUNCTION reg_replace(subject VARCHAR(21845), pattern VARCHAR(21845),
replacement VARCHAR(21845), greedy BOOLEAN, minMatchLen INT, maxMatchLen INT)
RETURNS VARCHAR(21845) DETERMINISTIC BEGIN
DECLARE result, subStr, usePattern VARCHAR(21845);
DECLARE startPos, prevStartPos, startInc, len, lenInc INT;
IF subject REGEXP pattern THEN
SET result = '';
SET minMatchLen = IF(minMatchLen < 1, 1, minMatchLen);
SET maxMatchLen = IF(maxMatchLen < 1 OR maxMatchLen > CHAR_LENGTH(subject),
CHAR_LENGTH(subject), maxMatchLen);
SET usePattern = IF (LEFT(pattern, 1) = '^', pattern, CONCAT('^', pattern));
SET usePattern = IF (RIGHT(pattern, 1) = '$', usePattern, CONCAT(usePattern, '$'));
IF LEFT(pattern, 1) = '^' OR RIGHT(pattern, 1) <> '$' THEN
SET startPos = 1, startInc = 1;
ELSEIF greedy THEN
SET startPos = CHAR_LENGTH(subject) - maxMatchLen + 1, startInc = 1;
ELSE
SET startPos = CHAR_LENGTH(subject) - minMatchLen + 1, startInc = -1;
END IF;
WHILE startPos >= 1 AND startPos <= CHAR_LENGTH(subject)
AND startPos + minMatchLen - 1 <= CHAR_LENGTH(subject)
AND !(LEFT(pattern, 1) = '^' AND startPos <> 1)
AND !(RIGHT(pattern, 1) = '$'
AND startPos + maxMatchLen - 1 < CHAR_LENGTH(subject)) DO
IF greedy OR RIGHT(pattern, 1) = '$' THEN
SET len = LEAST(CHAR_LENGTH(subject) - startPos + 1, maxMatchLen), lenInc = -1;
ELSE
SET len = minMatchLen, lenInc = 1;
END IF;
SET prevStartPos = startPos;
lenLoop: WHILE len >= 1 AND len <= maxMatchLen
AND startPos + len - 1 <= CHAR_LENGTH(subject)
AND !(RIGHT(pattern, 1) = '$'
AND startPos + len - 1 <> CHAR_LENGTH(subject)) DO
SET subStr = SUBSTRING(subject, startPos, len);
IF subStr REGEXP usePattern THEN
SET result = IF(startInc = 1,
CONCAT(result, replacement), CONCAT(replacement, result));
SET startPos = startPos + startInc * len;
LEAVE lenLoop;
END IF;
SET len = len + lenInc;
END WHILE;
IF (startPos = prevStartPos) THEN
SET result = IF(startInc = 1, CONCAT(result, SUBSTRING(subject, startPos, 1)),
CONCAT(SUBSTRING(subject, startPos, 1), result));
SET startPos = startPos + startInc;
END IF;
END WHILE;
IF startInc = 1 AND startPos <= CHAR_LENGTH(subject) THEN
SET result = CONCAT(result, RIGHT(subject, CHAR_LENGTH(subject) + 1 - startPos));
ELSEIF startInc = -1 AND startPos >= 1 THEN
SET result = CONCAT(LEFT(subject, startPos), result);
END IF;
ELSE
SET result = subject;
END IF;
RETURN result;
END;
DROP FUNCTION IF EXISTS format_result;
CREATE FUNCTION format_result(result VARCHAR(21845))
RETURNS VARCHAR(21845) DETERMINISTIC BEGIN
RETURN CONCAT(CONCAT('|', REPLACE(REPLACE(REPLACE(REPLACE(result, '\t', '\\t'), CHAR(12), '\\f'), '\r', '\\r'), '\n', '\\n')), '|');
END;
DROP TABLE IF EXISTS tbl;
CREATE TABLE tbl
AS
SELECT 'Afghanistan' AS txt
UNION ALL
SELECT ' AF' AS txt
UNION ALL
SELECT ' Cayman Islands ' AS txt
UNION ALL
SELECT CONCAT(CONCAT(CONCAT('\t \t ', CHAR(12)), ' \r\n\t British Virgin Islands \t \t ', CHAR(12)), ' \r\n') AS txt;
SELECT format_result(txt) AS txt,
format_result(TRIM(txt)) AS trim,
format_result(TRIM(BOTH '\r' FROM TRIM(BOTH '\n' FROM TRIM(BOTH '\f' FROM TRIM(BOTH '\t' FROM TRIM(txt))))))
AS `trim spaces, tabs, formfeeds and line endings`,
format_result(reg_replace(reg_replace(txt, '^[[:space:]]+', '', TRUE, 1, 0), '[[:space:]]+$', '', TRUE, 1, 0))
AS `reg_replace`
FROM tbl;
การใช้งาน:
SELECT reg_replace(
reg_replace(txt,
'^[[:space:]]+',
'',
TRUE,
1,
0),
'[[:space:]]+$',
'',
TRUE,
1,
0) AS `trimmed txt`
FROM tbl;