String 如何从字符串中删除任何尾随数字?
样本输入: “你好,你好吗?” “纽约的第一家比萨饼店是什么?” “多米诺骨牌是第一” “胡说八道123123” “更多废话12321123132” 预期产出: “你好,你好吗?” “纽约的第一家比萨饼店是什么?” “多米诺骨牌是数字” “废话” “更多废话” 我认为这是一个两步的过程:String 如何从字符串中删除任何尾随数字?,string,sql-server-2008,tsql,String,Sql Server 2008,Tsql,样本输入: “你好,你好吗?” “纽约的第一家比萨饼店是什么?” “多米诺骨牌是第一” “胡说八道123123” “更多废话12321123132” 预期产出: “你好,你好吗?” “纽约的第一家比萨饼店是什么?” “多米诺骨牌是数字” “废话” “更多废话” 我认为这是一个两步的过程: 将整个字符串按相反的顺序拆分为字符,每个字符一行(包括空格) 循环遍历,如果是空格或数字,则跳过,否则添加到另一个数组的开始 我会得到想要的结果 我可以想出一些快速而肮脏的方法,但这需要执行得相当好,因为它是一
--DECLARE @String VARCHAR(100) = 'the fat cat sat on the mat'
--DECLARE @String VARCHAR(100) = 'the fat cat 2 sat33 on4 the mat'
--DECLARE @String VARCHAR(100) = 'the fat cat sat on the mat1'
--DECLARE @String VARCHAR(100) = '2121'
DECLARE @String VARCHAR(100) = 'the fat cat 2 2 2 2 sat on the mat2121'
DECLARE @Answer NVARCHAR(MAX),
@Index INTEGER = LEN(@String),
@Character CHAR,
@IncorrectCharacterIndex SMALLINT
-- Start from the end, going to the front.
WHILE @Index > 0 BEGIN
-- Get each character, starting from the end
SET @Character = SUBSTRING(@String, @Index, 1)
-- Regex check.
SET @IncorrectCharacterIndex = PATINDEX('%[A-Za-z-]%', @Character)
-- Is there a match? We're lucky here because it will either match on index 1 or not (index 0)
IF (@IncorrectCharacterIndex != 0)
BEGIN
-- We have a legit character.
SET @Answer = SUBSTRING(@String, 0, @Index + 1)
SET @Index = 0
END
ELSE
SET @Index = @Index - 1 -- No match, lets go back one index slot.
END
PRINT LTRIM(RTRIM(@Answer))
注意:我在有效的正则表达式匹配中包含了破折号。繁忙表上的循环不太可能充分执行。使用REVERSE和PATINDEX查找第一个非数字,在那里开始一个子字符串,然后反转结果。这将非常缓慢,没有循环 您的示例暗示您也不希望匹配空格
DECLARE @t TABLE (s NVARCHAR(500))
INSERT INTO @t (s)
VALUES
('Hi there how are you'),('What is the #1 pizza place in NYC?'),('Dominoes is number 1'),('Blah blah 123123'),('More blah 12321 123123 123132')
select s
, reverse(s) as beginning
, patindex('%[^0-9 ]%',reverse(s)) as progress
, substring(reverse(s),patindex('%[^0-9 ]%',reverse(s)), 1+len(s)-patindex('%[^0-9 ]%',reverse(s))) as [more progress]
, reverse(substring(reverse(s),patindex('%[^0-9 ]%',reverse(s)), 1+len(s)-patindex('%[^0-9 ]%',reverse(s)))) as SOLUTION
from @t
最后答覆:
反向(子字符串(反向(@s)、patindex('%[^0-9]]'、反向(@s))、1+len(@s)-patindex('%[^0-9]'、反向(@s))此解决方案应该更有效,因为它首先检查字符串是否包含数字,然后检查字符串是否以数字结尾
CREATE FUNCTION dbo.trim_ending_numbers(@columnvalue AS VARCHAR(100)) RETURNS VARCHAR(100)
BEGIN
--This will make the query more efficient by first checking to see if it contains any numbers at all
IF @columnvalue NOT LIKE '%[0-9]%'
RETURN @columnvalue
DECLARE @counter INT
SET @counter = LEN(@columnvalue)
IF ISNUMERIC(SUBSTRING(@columnvalue,@counter,1)) = 0
RETURN @columnvalue
WHILE ISNUMERIC(SUBSTRING(@columnvalue,@counter,1)) = 1 OR SUBSTRING(@columnvalue,@counter,1) = ' '
BEGIN
SET @counter = @counter -1
IF @counter < 0
BREAK
END
SET @columnvalue = SUBSTRING(@columnvalue,0,@counter+1)
RETURN @columnvalue
END
它会回来的
'More blah'
感谢所有对我们很有帮助的贡献。要进一步提取尾随数字,请执行以下操作:
, substring(s, 2 + len(s) - patindex('%[^0-9 ]%',reverse(s)), 99) as numeric_suffix
我需要根据数字后缀进行排序,因此必须将模式限制为数字,并将不同长度的数字作为文本排序(即我希望2在19之前排序)转换结果:
,cast(substring(s, 2 + len(s) - patindex('%[^0-9]%',reverse(s)),99) as integer) as numeric_suffix
我相信下面的查询是快速而有用的
select reverse(substring(reverse(colA),PATINDEX('%[0-9][a-z]%',reverse(colA))+1,
len(colA)-PATINDEX('%[0-9][a-z]%',reverse(colA))))
from TBLA
我正在做一件比你的两步流程中所描述的更有效率的事情,给我几分钟。@zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz@RPM1984-除非你一直在吃虫子,否则它是“减弱”的。我相信我的答案很快而且更有用。测试一个字符是否是一个数字而不是一个字母不是更有效吗?不过,性能差异可能不大。当然可以我完全忘记了
IsNumeric
关键字。我在一个30000多行的SQL Server 2008数据库上测试了它,耗时<1秒。SQL中的循环速度很慢,而IsNumeric()并不像您想象的那样。尝试选择ISNUMERIC(“.”)、ISNUMERIC(“$”)、ISNUMERIC('1e7')以及更多在不只是数字时返回true的项。这是一个很好的建议,但您可以将其缩短一点<代码>子字符串(s,1,1+len(s)-patindex(“%[^0-9]]”,反向))这应该是注释,而不是答案。检查此项以及如何给出正确答案。PATINDEX表达式“%[0-9][a-z]”仅查找字母附近的数字,并且上面的示例输入在它们之间有一个空格。所以它必须是“%[0-9][a-z]%”。或者,如果要与任何非数字匹配,请使用“%[0-9][^0-9]%”
select reverse(substring(reverse(colA),PATINDEX('%[0-9][a-z]%',reverse(colA))+1,
len(colA)-PATINDEX('%[0-9][a-z]%',reverse(colA))))
from TBLA