2015-04-17 36 views
0

我有一个字段与此值:MySQL的正则表达式替换查询

TEST:ATEST:TESTA 

而且我想用“新”来代替“TEST”,我曾尝试此查询:

UPDATE `table` SET `field` = REPLACE(`field`, 'TEST', 'NEW') WHERE `field` REGEXP 'TEST'; 

结果是:

NEW:ANEW:NEWA 

问:我怎么能这样做替换查询所以结果会是这样:

NEW:ATEST:TESTA 
+1

所以文'TEST'可能出现在任何地方或只是在第一个地方? –

+0

请考虑以下解决方案在这里: http://stackoverflow.com/questions/986826/how-to-do-a-regular-expression-replace-in-mysql – Andriy

+0

良好的渔获@Abhikda,+1,所以如果TEST出现在第一位,我们可以使用“^”来匹配开头 –

回答

0

这是一个有点痛,但你可以这样来做:

UPDATE `table` 
    SET field = substr(REPLACE(concat(':', field, ':'), ':TEST:', ':NEW:'), 
         2, length(REPLACE(concat(':', field, ':'), ':TEST:', ':NEW:')) - 2) 
    WHERE concat(':', field, ':') LIKE '%:TEST:%'; 

我喜欢LIKEREGEXP,因为有一种能够使用索引的希望。在这种情况下,这不是一种可能性,但有希望。

这是用开头和结尾的冒号分隔值,并且只替换完全分隔的值。诀窍是然后删除额外的冒号。

+0

它的工作原理。谢谢! – iTesTi

0

您可以尝试http://sqlfiddle.com/#!9/4e66b/3

所以更新查询(如表名=表1,字段名=字段1,并有独特的列ID):

UPDATE `table1` 
INNER JOIN 
    (SELECT id, 
    @set_idx:=FIND_IN_SET('TEST',REPLACE(field1,':',',')), 
    @set_size:=LENGTH(field1)-LENGTH(REPLACE(field1,':',''))+1, 
    CASE 
     WHEN @set_idx=1 THEN CONCAT('NEW',SUBSTRING(field1, 4)) 
     WHEN @set_idx>1 THEN CONCAT(SUBSTRING_INDEX(field1, ':',@set_idx-1),':NEW', IF(@set_size>@set_idx,CONCAT(':',SUBSTRING_INDEX(field1, ':',-(@[email protected]_idx))),'')) 
    END as new 
    FROM table1 
    WHERE `field1` REGEXP '(^TEST$)|(^TEST:)|(:TEST$)|(:TEST:)' 
    ) t 
ON t.id = table1.id 
SET table1.field1 = t.new;