SQL里面的正则expression式replace函数?
SELECT REPLACE('<strong>100</strong><b>.00 GB', '%^(^-?\d*\.{0,1}\d+$)%', '');
我想用上面的正则expression式replace数字的两个部分之间的任何标记,但似乎没有工作。 我不确定这是不是正则expression式语法错了,因为我尝试了一个简单的例如'%[^0-9]%'
来testing,但它也不起作用。 有谁知道我怎么能做到这一点?
您可以使用PATINDEX查找模式(string)出现的第一个索引。 然后使用STUFF将另一个string填充到匹配的模式(string)中。
循环通过每一行。 用你想要的replace每个非法字符。 在你的情况下,用空白replace非数字。 内循环是,如果在循环当前单元中有多个非法字符。
DECLARE @counter int SET @counter = 0 WHILE(@counter < (SELECT MAX(ID_COLUMN) FROM Table)) BEGIN WHILE 1 = 1 BEGIN DECLARE @RetVal varchar(50) SET @RetVal = (SELECT Column = STUFF(Column, PATINDEX('%[^0-9.]%', Column),1, '') FROM Table WHERE ID_COLUMN = @counter) IF(@RetVal IS NOT NULL) UPDATE Table SET Column = @RetVal WHERE ID_COLUMN = @counter ELSE break END SET @counter = @counter + 1 END
警告:虽然这很慢! 有一个varchar列可能会影响。 所以使用LTRIM RTRIM可能会有所帮助。 无论如何,这是缓慢的。
积分转到这个 StackOverFlow答案。
编辑信贷也去@srutzky
编辑(by @Tmdean)这个答案可以适应更多基于集合的解决scheme,而不是一次只做一行。 它仍然在一行中迭代非数字字符的数量的最大值,所以它不是理想的,但我认为在大多数情况下它应该是可以接受的。
WHILE 1 = 1 BEGIN WITH q AS (SELECT ID_Column, PATINDEX('%[^0-9.]%', Column) AS n FROM Table) UPDATE Table SET Column = STUFF(Column, qn, 1, '') FROM q WHERE Table.ID_Column = q.ID_Column AND qn != 0; IF @@ROWCOUNT = 0 BREAK; END;
如果您在表格中保留了一个表示该字段是否已被清理的列,也可以提高效率。 (在我的例子中NULL代表“未知”,应该是列的默认值。)
DECLARE @done bit = 0; WHILE @done = 0 BEGIN WITH q AS (SELECT ID_Column, PATINDEX('%[^0-9.]%', Column) AS n FROM Table WHERE COALESCE(Scrubbed_Column, 0) = 0) UPDATE Table SET Column = STUFF(Column, qn, 1, ''), Scrubbed_Column = 0 FROM q WHERE Table.ID_Column = q.ID_Column AND qn != 0; IF @@ROWCOUNT = 0 SET @done = 1; -- if Scrubbed_Column is still NULL, then the PATINDEX -- must have given 0 UPDATE table SET Scrubbed_Column = CASE WHEN Scrubbed_Column IS NULL THEN 1 ELSE NULLIF(Scrubbed_Column, 0) END; END;
如果你不想改变你的模式,这很容易适应将中间结果存储在一个表值variables中,这个variables在最后被应用到实际的表中。
一般来说,SQL Server不支持正则expression式,不能在原生T-SQL代码中使用它们。
你可以写一个CLR函数来做到这一点。 例如,看这里 。
使用Replace(Column, BadFoundCharacter, '')
可以大大加快速度Replace(Column, BadFoundCharacter, '')
而不是将所find的字符剥离出其唯一的位置。 此外,而不是只replace每个列中的下一个坏字符,这将取代所有发现的。
WHILE 1 = 1 BEGIN UPDATE dbo.YourTable SET Column = Replace(Column, Substring(Column, PatIndex('%[^0-9.-]%', Column), 1), '') WHERE Column LIKE '%[^0-9.-]%' If @@RowCount = 0 BREAK; END;
我相信这会比接受的答案更好,如果只是因为它的操作更less。 还有其他方法可能也会更快,但我现在没有时间去探索这些方法。
如果你想重复使用,将解决scheme包装在SQL函数中可能会很有用。 我甚至在单元格级别做这个,为什么我把这个不同的答案:
CREATE FUNCTION [dbo].[fnReplaceInvalidChars] (@string VARCHAR(300)) RETURNS VARCHAR(300) BEGIN DECLARE @str VARCHAR(300) = @string; DECLARE @Pattern VARCHAR (20) = '%[^a-zA-Z0-9]%'; DECLARE @Len INT; SELECT @Len = LEN(@String); WHILE @Len > 0 BEGIN SET @Len = @Len - 1; IF (PATINDEX(@Pattern,@str) > 0) BEGIN SELECT @str = STUFF(@str, PATINDEX(@Pattern,@str),1,''); END ELSE BEGIN BREAK; END END RETURN @str END
如果您只是为了进入存储过程的参数执行此操作,则可以使用以下方法:
while PatIndex('%[^0-9]%', @Param) > 0 select @Param = Replace(@Param, Substring(@Param, PatIndex('%[^0-9]%', @Param), 1), '')