Làm thế nào để thực hiện một biểu thức chính quy thay thế trong MySQL?


516

Tôi có một bảng với hàng ~ 500k; cột varchar (255) UTF8 filenamechứa tên tệp;

Tôi đang cố gắng loại bỏ các ký tự lạ khác nhau khỏi tên tệp - nghĩ rằng tôi sẽ sử dụng một lớp nhân vật: [^a-zA-Z0-9()_ .\-]

Bây giờ, có một chức năng trong MySQL cho phép bạn thay thế thông qua một biểu thức thông thường không? Tôi đang tìm một chức năng tương tự như hàm REPLACE () - ví dụ đơn giản hóa như sau:

SELECT REPLACE('stackowerflow', 'ower', 'over');

Output: "stackoverflow"

/* does something like this exist? */
SELECT X_REG_REPLACE('Stackoverflow','/[A-Zf]/','-'); 

Output: "-tackover-low"

Tôi biết về REGEXP / RLIKE , nhưng những chỉ kiểm tra nếu có một trận đấu, chứ không phải những gì trận đấu là.

(Tôi có thể thực hiện " SELECT pkey_id,filename FROM foo WHERE filename RLIKE '[^a-zA-Z0-9()_ .\-]'" từ tập lệnh PHP, thực hiện preg_replacerồi " UPDATE foo ... WHERE pkey_id=...", nhưng đó có vẻ như là một bản hack chậm và xấu xí cuối cùng)


8
Đây là một yêu cầu tính năng kể từ năm 2007: bug.mysql.com/orms.php?id=27389 . Nếu bạn thực sự muốn tính năng này, hãy đăng nhập và nhấp vào nút "Ảnh hưởng đến tôi". Hy vọng nó sẽ nhận được đủ số phiếu.
TMS

4
@Tomas: Tôi đã làm điều đó ... vào năm 2009, khi tôi đang tìm kiếm nó. Vì không có tiến triển nào về nó - rõ ràng nó không phải là một tính năng quan trọng như vậy. (btw Postgres có nó: stackoverflow.com/questions/11722995/ triệt )
Piskvor rời khỏi tòa nhà vào

1
Liên quan, đơn giản hơn, phiên bản của câu hỏi này: stackoverflow.com/questions/6942973/
Kẻ

2
Tôi đã tạo regexp_split(hàm + thủ tục) & regexp_replace, được triển khai với REGEXPtoán tử. Đối với tra cứu đơn giản, nó sẽ làm thủ thuật. Bạn có thể tìm thấy nó ở đây - vì vậy, đây là cách với mã được lưu trữ MySQL, không có UDF. Nếu bạn sẽ tìm thấy một số lỗi không được giới hạn bởi các giới hạn đã biết - vui lòng mở vấn đề.
Alma Do

1
Tìm thấy thư viện này từ một luồng SO khác: github.com/mysqludf/lib_mysqludf_preg hoạt động hoàn hảo.
Kyle

Câu trả lời:


78

Với MySQL 8.0+, bạn có thể sử dụng REGEXP_REPLACEchức năng hữu cơ .

12.5.2 Biểu thức chính quy :

REGEXP_REPLACE(expr, pat, repl[, pos[, occurrence[, match_type]]])

Thay thế xuất hiện trong chuỗi expr phù hợp với biểu thức chính quy theo quy định của mô hình pat với chuỗi thay thế repl , và trả về chuỗi kết quả. Nếu expr , pat , hoặc replNULL, giá trị trả về là NULL.

hỗ trợ biểu thức chính quy :

Trước đây, MySQL đã sử dụng thư viện biểu thức chính quy Henry Spencer để hỗ trợ các toán tử biểu thức chính quy ( REGEXP, RLIKE).

Hỗ trợ biểu thức chính quy đã được triển khai lại bằng cách sử dụng Các thành phần quốc tế cho Unicode (ICU), cung cấp hỗ trợ Unicode đầy đủ và an toàn đa khung. Các REGEXP_LIKE()chức năng thực hiện phù hợp với biểu thức chính quy theo cách của REGEXPRLIKEcác nhà khai thác, mà bây giờ là từ đồng nghĩa cho chức năng đó. Ngoài ra, các REGEXP_INSTR(), REGEXP_REPLACE()và các REGEXP_SUBSTR() hàm có sẵn để tìm vị trí khớp và thực hiện thay thế và trích xuất chuỗi con tương ứng.

SELECT REGEXP_REPLACE('Stackoverflow','[A-Zf]','-',1,0,'c'); 
-- Output:
-tackover-low

Trình diễn DBFiddle


147

MySQL 8.0+ :

Bạn có thể sử dụng REGEXP_REPLACEchức năng bản địa .

Các phiên bản cũ hơn:

Bạn có thể sử dụng một hàm do người dùng định nghĩa ( UDF ) như mysql-udf-regapi .


3
REGEXP_REPLACE là Hàm do người dùng xác định? Có vẻ hứa hẹn, sẽ nhìn vào nó. Cảm ơn!
Piskvor rời khỏi tòa nhà

15
Thật không may, mysql-udf-regapi dường như không hỗ trợ các ký tự đa nhân. regrec_Vplace ('äöõü', 'ä', '') trả về một chuỗi số dài thay vì văn bản thực.
lkraav

3
Bản thân MySQL không hỗ trợ các ký tự nhiều byte với các tính năng RegEx.
Brad

4
Người dùng Windows: Thư viện UDF được liên kết ở đây dường như không hỗ trợ windows tốt. Phương pháp cài đặt windows được phác thảo không hoạt động tốt đối với tôi.
Jonathan

2
@lkraav bạn nên dùng thử thư viện lib_mysqludf_preg dưới đây vì nó hoạt động rất tốt. Đây là phiên bản dài dòng vì nó trả về một blob theo mặc định và tôi không biết liệu bạn có bộ ký tự đa bào làm mặc định hay không: chọn cast (TR as char) COLLATE utf8_unicode_ci từ (chọn preg numplace ('/ ä /', '', 'öõüä') R) T
gillyspy

124

Sử dụng MariaDB thay thế. Nó có chức năng

REGEXP_REPLACE(col, regexp, replace)

Xem tài liệu MariaDBPCRE Cải tiến biểu thức chính quy

Lưu ý rằng bạn cũng có thể sử dụng nhóm regrec (tôi thấy điều đó rất hữu ích):

SELECT REGEXP_REPLACE("stackoverflow", "(stack)(over)(flow)", '\\2 - \\1 - \\3')

trả lại

over - stack - flow

12
đây là từ mariadb 10
Nick

6
Lần sau tôi cần nó, đây là cú pháp để thay đổi toàn bộ một cột: UPDATE table SET Name = REGEXP_REPLACE(Name, "-2$", "\\1")Điều này loại bỏ -2 khỏi abcxyz-2 khỏi toàn bộ một cột.
Giô

27
Thay đổi toàn bộ nền tảng hầu như không phải là một giải pháp thực tế.
David Baucum

3
@DavidBaucum MariaDB là một thay thế thả xuống cho MySQL. Vì vậy, đó không phải là "thay đổi nền tảng" mà giống như chọn một hãng hàng không khác cho cùng một chuyến đi
Benvorth


113

Phương pháp vũ phu của tôi để làm việc này chỉ là:

  1. Đổ bàn - mysqldump -u user -p database table > dump.sql
  2. Tìm và thay thế một vài mẫu - find /path/to/dump.sql -type f -exec sed -i 's/old_string/new_string/g' {} \;, Rõ ràng cũng có các biểu thức regeular perl khác mà bạn có thể thực hiện trên tệp.
  3. Nhập bảng - mysqlimport -u user -p database table < dump.sql

Nếu bạn muốn đảm bảo chuỗi không ở đâu trong tập dữ liệu của bạn, hãy chạy một vài biểu thức chính quy để đảm bảo tất cả chúng xảy ra trong một môi trường tương tự. Cũng không khó để tạo một bản sao lưu trước khi bạn chạy thay thế, trong trường hợp bạn vô tình phá hủy thứ gì đó làm mất thông tin.


33
Được rồi, điều đó cũng nên làm việc; Tôi đã không xem xét một sự thay thế ngoại tuyến. Đẹp ngoài kia nghĩ!
Piskvor rời khỏi tòa nhà

10
Có vẻ lạ đối với tôi rằng bạn sẽ sử dụng find như thế, tôi sẽ rút ngắn lệnh thành sed -i 's / old_opes / new_opes / g' /path/to/dump.sql
speshak

36
Rất rủi ro và không thực tế với các tập dữ liệu lớn hoặc có tính toàn vẹn tham chiếu: để xóa dữ liệu và sau đó chèn lại, bạn sẽ phải tắt tính toàn vẹn tham chiếu, thực tế cũng tắt cơ sở dữ liệu của bạn.
Raul Luna

5
Đã từng sử dụng phương pháp này trong quá khứ, tôi rất thích Raul, điều này rất rủi ro. Bạn cũng cần phải hoàn toàn chắc chắn rằng chuỗi của bạn không có ở đâu trong tập dữ liệu của bạn.
đánh trứng

1
Nhiều năm sau câu trả lời @speshak nhưng lý do tôi chọn truy cập tệp như thế này là vì ban đầu tôi rất lo lắng vì những lý do tương tự như đã đề cập ở trên. Vào thời điểm đó, có vẻ như tách phần "tìm tệp" khỏi phần "thay thế" sẽ giúp mã dễ đọc hơn trước khi tôi gửi nó
Ryan Ward

42

chúng tôi giải quyết vấn đề này mà không sử dụng regex truy vấn này chỉ thay thế chuỗi khớp chính xác.

update employee set
employee_firstname = 
trim(REPLACE(concat(" ",employee_firstname," "),' jay ',' abc '))

Thí dụ:

emp_id worker_firstname

1 tháng giêng

2 ngày mai

3 tháng ba

Sau khi thực hiện kết quả truy vấn:

emp_id worker_firstname

1 abc

2 ngày mai

3 abc


@yellowiwi Hai cặp dấu ngoặc kép để làm gì?
codecowboy 4

5
Anh ấy đệm việc làm với không gian trước và sau. Điều này cho phép anh ta tìm kiếm thay thế cho (không gian) Employeename (không gian), điều này giúp tránh việc bắt nhân viên "jay" nếu đó là một phần của chuỗi "ajay" lớn hơn. Sau đó, anh ấy cắt không gian ra khi hoàn thành.
Slam

42

Gần đây tôi đã viết một hàm MySQL để thay thế các chuỗi bằng các biểu thức thông thường. Bạn có thể tìm thấy bài viết của tôi tại vị trí sau:

http://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/

Đây là mã chức năng:

DELIMITER $$

CREATE FUNCTION  `regex_replace`(pattern VARCHAR(1000),replacement VARCHAR(1000),original VARCHAR(1000))
RETURNS VARCHAR(1000)
DETERMINISTIC
BEGIN 
 DECLARE temp VARCHAR(1000); 
 DECLARE ch VARCHAR(1); 
 DECLARE i INT;
 SET i = 1;
 SET temp = '';
 IF original REGEXP pattern THEN 
  loop_label: LOOP 
   IF i>CHAR_LENGTH(original) THEN
    LEAVE loop_label;  
   END IF;
   SET ch = SUBSTRING(original,i,1);
   IF NOT ch REGEXP pattern THEN
    SET temp = CONCAT(temp,ch);
   ELSE
    SET temp = CONCAT(temp,replacement);
   END IF;
   SET i=i+1;
  END LOOP;
 ELSE
  SET temp = original;
 END IF;
 RETURN temp;
END$$

DELIMITER ;

Ví dụ thực hiện:

mysql> select regex_replace('[^a-zA-Z0-9\-]','','2my test3_text-to. check \\ my- sql (regular) ,expressions ._,');

25
Tôi sẽ chỉ củng cố điểm trên: hàm này thay thế các ký tự khớp với biểu thức một ký tự. Nó nói ở trên rằng nó được sử dụng "để đánh giá lại các chuỗi bằng các biểu thức thông thường" và điều đó có thể gây hiểu nhầm đôi chút. Nó làm công việc của nó, nhưng nó không phải là công việc được yêu cầu. (Không phải là một khiếu nại - đó chỉ là để cứu những người dẫn đầu đi sai đường)
Jason

2
Sẽ hữu ích hơn khi thực sự bao gồm mã trong câu trả lời của bạn thay vì đăng một liên kết trần trụi.
phobie

2
Đẹp - nhưng tiếc là không xử lý các tài liệu tham khảo như select regex_replace('.*(abc).*','\1','noabcde')(trả về 'noabcde', không phải 'abc').
Izzy

@phobie người khác đã làm điều đó trong câu trả lời này - chỉ như một tài liệu tham khảo trong trường hợp liên kết chết;)
Izzy

Tôi đã sửa đổi phương pháp này để cố gắng giải quyết một số hạn chế được đề cập ở trên và hơn thế nữa. Xin vui lòng xem câu trả lời này .
Steve Chambers


13

CẬP NHẬT 2: Một tập hợp các hàm regex hữu ích bao gồm REGEXP_REPLACE hiện đã được cung cấp trong MySQL 8.0. Điều này ám chỉ việc đọc không cần thiết trừ khi bạn bị hạn chế sử dụng phiên bản cũ hơn.


CẬP NHẬT 1: Hiện tại đã biến bài viết này thành một bài đăng trên blog: http://stevettt.blogspot.co.uk/2018/02/a-mysql-THER-expression-replace.html


Phần sau đây mở rộng dựa trên chức năng do Rasika Godawatte cung cấp nhưng truy tìm tất cả các chuỗi con cần thiết thay vì chỉ kiểm tra các ký tự đơn:

-- ------------------------------------------------------------------------------------
-- USAGE
-- ------------------------------------------------------------------------------------
-- SELECT reg_replace(<subject>,
--                    <pattern>,
--                    <replacement>,
--                    <greedy>,
--                    <minMatchLen>,
--                    <maxMatchLen>);
-- where:
-- <subject> is the string to look in for doing the replacements
-- <pattern> is the regular expression to match against
-- <replacement> is the replacement string
-- <greedy> is TRUE for greedy matching or FALSE for non-greedy matching
-- <minMatchLen> specifies the minimum match length
-- <maxMatchLen> specifies the maximum match length
-- (minMatchLen and maxMatchLen are used to improve efficiency but are
--  optional and can be set to 0 or NULL if not known/required)
-- Example:
-- SELECT reg_replace(txt, '^[Tt][^ ]* ', 'a', TRUE, 2, 0) FROM tbl;
DROP FUNCTION IF EXISTS reg_replace;
DELIMITER //
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 = '';
    -- Sanitize input parameter values
    SET minMatchLen = IF(minMatchLen < 1, 1, minMatchLen);
    SET maxMatchLen = IF(maxMatchLen < 1 OR maxMatchLen > CHAR_LENGTH(subject),
                         CHAR_LENGTH(subject), maxMatchLen);
    -- Set the pattern to use to match an entire string rather than part of a string
    SET usePattern = IF (LEFT(pattern, 1) = '^', pattern, CONCAT('^', pattern));
    SET usePattern = IF (RIGHT(pattern, 1) = '$', usePattern, CONCAT(usePattern, '$'));
    -- Set start position to 1 if pattern starts with ^ or doesn't end with $.
    IF LEFT(pattern, 1) = '^' OR RIGHT(pattern, 1) <> '$' THEN
      SET startPos = 1, startInc = 1;
    -- Otherwise (i.e. pattern ends with $ but doesn't start with ^): Set start pos
    -- to the min or max match length from the end (depending on "greedy" flag).
    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
      -- Set start length to maximum if matching greedily or pattern ends with $.
      -- Otherwise set starting length to the minimum match length.
      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//
DELIMITER ;

Bản giới thiệu

Trình diễn Rextester

Hạn chế

  1. Phương pháp này tất nhiên sẽ mất một lúc khi chuỗi chủ đề lớn. Cập nhật: Hiện đã thêm các tham số độ dài khớp tối thiểu và tối đa để cải thiện hiệu quả khi chúng được biết đến (zero = unknown / Unlimited).
  2. sẽ không cho phép thay thế các phản hồi (ví dụ \1, \2 v.v.) để thay thế các nhóm bắt giữ. Nếu chức năng này là cần thiết, vui lòng xem câu trả lời này cố gắng cung cấp cách giải quyết bằng cách cập nhật chức năng để cho phép tìm và thay thế thứ cấp trong mỗi kết quả tìm thấy (với chi phí tăng độ phức tạp).
  3. Nếu ^và / hoặc $được sử dụng trong mẫu, chúng phải ở đầu và cuối tương ứng - ví dụ như các mẫu như (^start|end$)không được hỗ trợ.
  4. Có một cờ "tham lam" để xác định xem kết hợp tổng thể nên tham lam hay không tham lam. Kết hợp kết hợp tham lam và lười biếng trong một biểu thức chính quy duy nhất (ví dụ a.*?b.*) không được hỗ trợ.

Ví dụ sử dụng

Hàm đã được sử dụng để trả lời các câu hỏi StackOverflow sau:


7

Bạn 'có thể làm điều đó ... nhưng nó không khôn ngoan lắm ... điều này cũng táo bạo như tôi sẽ thử ... chừng nào RegEx hỗ trợ bạn tốt hơn nhiều bằng cách sử dụng perl hoặc tương tự.

UPDATE db.tbl
SET column = 
CASE 
WHEN column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]' 
THEN REPLACE(column,'WORD_TO_REPLACE','REPLACEMENT')
END 
WHERE column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]'

1
Không, nó sẽ không hoạt động. Hãy tưởng tượng cột của bạn chứa 'asdfWORD_TO_REPLACE WORD_TO_REPLACE ". Phương pháp của bạn sẽ dẫn đến' asdfREPLACEMENT REPLACMENT" trong đó câu trả lời đúng sẽ là "asdfWORD_TO_REPLACE REPLACMENT".
Ryan Shillington

1
@Ryan ... đó chính xác là lý do tại sao tôi tuyên bố rằng nó không khôn ngoan ... trong trường hợp sử dụng mà bạn cung cấp, điều này chắc chắn sẽ thất bại. Nói tóm lại, đó là một ý tưởng tồi để sử dụng cấu trúc 'giống như regex'. Thậm chí tệ hơn ... nếu bạn bỏ mệnh đề where, tất cả các giá trị của bạn sẽ là NULL ...
Eddie B

1
Trên thực tế Ryan trong trường hợp này bạn không chính xác như các dấu hiệu sẽ chỉ tìm thấy trận đấu cho từ zero-length 'ranh giới' để chỉ những lời có ranh giới trước và sau chữ sẽ phù hợp với ... Nó vẫn là một ý tưởng tồi mặc dù ...
Eddie B

6

Chúng ta có thể sử dụng điều kiện IF trong truy vấn SELECT như dưới đây:

Giả sử rằng đối với mọi thứ có "ABC", "ABC1", "ABC2", "ABC3", ..., chúng tôi muốn thay thế bằng "ABC" sau đó sử dụng điều kiện REGEXP và IF () trong truy vấn SELECT, chúng tôi có thể đạt được điều này .

Cú pháp:

SELECT IF(column_name REGEXP 'ABC[0-9]$','ABC',column_name)
FROM table1 
WHERE column_name LIKE 'ABC%';

Thí dụ:

SELECT IF('ABC1' REGEXP 'ABC[0-9]$','ABC','ABC1');

Xin chào, cảm ơn bạn đã gợi ý. Tôi đã thử một cái gì đó tương tự, nhưng hiệu suất trên các tập dữ liệu của tôi không đạt yêu cầu. Đối với các bộ nhỏ, điều này có thể khả thi.
Piskvor rời khỏi tòa nhà

3

Cái bên dưới về cơ bản tìm thấy trận đấu đầu tiên từ bên trái và sau đó thay thế tất cả các lần xuất hiện của nó (được thử nghiệm trong ).

Sử dụng:

SELECT REGEX_REPLACE('dis ambiguity', 'dis[[:space:]]*ambiguity', 'disambiguity');

Thực hiện:

DELIMITER $$
CREATE FUNCTION REGEX_REPLACE(
  var_original VARCHAR(1000),
  var_pattern VARCHAR(1000),
  var_replacement VARCHAR(1000)
  ) RETURNS
    VARCHAR(1000)
  COMMENT 'Based on https://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/'
BEGIN
  DECLARE var_replaced VARCHAR(1000) DEFAULT var_original;
  DECLARE var_leftmost_match VARCHAR(1000) DEFAULT
    REGEX_CAPTURE_LEFTMOST(var_original, var_pattern);
    WHILE var_leftmost_match IS NOT NULL DO
      IF var_replacement <> var_leftmost_match THEN
        SET var_replaced = REPLACE(var_replaced, var_leftmost_match, var_replacement);
        SET var_leftmost_match = REGEX_CAPTURE_LEFTMOST(var_replaced, var_pattern);
        ELSE
          SET var_leftmost_match = NULL;
        END IF;
      END WHILE;
  RETURN var_replaced;
END $$
DELIMITER ;

DELIMITER $$
CREATE FUNCTION REGEX_CAPTURE_LEFTMOST(
  var_original VARCHAR(1000),
  var_pattern VARCHAR(1000)
  ) RETURNS
    VARCHAR(1000)
  COMMENT '
  Captures the leftmost substring that matches the [var_pattern]
  IN [var_original], OR NULL if no match.
  '
BEGIN
  DECLARE var_temp_l VARCHAR(1000);
  DECLARE var_temp_r VARCHAR(1000);
  DECLARE var_left_trim_index INT;
  DECLARE var_right_trim_index INT;
  SET var_left_trim_index = 1;
  SET var_right_trim_index = 1;
  SET var_temp_l = '';
  SET var_temp_r = '';
  WHILE (CHAR_LENGTH(var_original) >= var_left_trim_index) DO
    SET var_temp_l = LEFT(var_original, var_left_trim_index);
    IF var_temp_l REGEXP var_pattern THEN
      WHILE (CHAR_LENGTH(var_temp_l) >= var_right_trim_index) DO
        SET var_temp_r = RIGHT(var_temp_l, var_right_trim_index);
        IF var_temp_r REGEXP var_pattern THEN
          RETURN var_temp_r;
          END IF;
        SET var_right_trim_index = var_right_trim_index + 1;
        END WHILE;
      END IF;
    SET var_left_trim_index = var_left_trim_index + 1;
    END WHILE;
  RETURN NULL;
END $$
DELIMITER ;

3

Tôi nghĩ rằng có một cách dễ dàng để đạt được điều này và nó hoạt động tốt với tôi.

Để CHỌN hàng bằng REGEX

SELECT * FROM `table_name` WHERE `column_name_to_find` REGEXP 'string-to-find'

Để CẬP NHẬT các hàng bằng REGEX

UPDATE `table_name` SET column_name_to_find=REGEXP_REPLACE(column_name_to_find, 'string-to-find', 'string-to-replace') WHERE column_name_to_find REGEXP 'string-to-find'

Tham khảo REGEXP: https://www.geekforgeek.org/mysql-THER-expressions-regapi/


Cảm ơn bạn :) Có thể thực hiện dễ dàng kể từ phiên bản 8.
Piskvor rời khỏi tòa nhà vào
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.