如何从字符串中删除任何尾随数字?

时间:2012-02-10 02:14:49

标签: string sql-server-2008 tsql

示例输入:

  

“你好,你好吗”

     

“纽约市排名第一的披萨店是什么?”

     

“Dominoes is number 1”

     

“Blah blah 123123”

     

“更多blah 12321 123123 123132”

预期产出:

  

“你好,你好吗”

     

“纽约市排名第一的披萨店是什么?”

     

“Dominoes is number”

     

“Blah blah”

     

“更多等等”

我认为这是一个两步过程:

  1. 将整个字符串拆分为字符,每个字符一行(包括空格),反向顺序
  2. 循环播放,如果是空格或数字,则跳过,否则添加到另一个数组的开始
  3. 我应该得到理想的结果。

    我可以想到一些快速而肮脏的方法,但这需要执行得相当好,因为它是一个在繁忙的桌子上运行的触发器,所以我想把它扔给T-SQL专业人员。

    有什么建议吗?

5 个答案:

答案 0 :(得分:4)

这个解决方案应该更有效率,因为它首先检查字符串是否包含数字,然后检查字符串是否以数字结尾。

 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

如果你跑

SELECT dbo.trim_ending_numbers('More blah 12321 123123 123132')

它会返回

'More blah'

答案 1 :(得分:3)

繁忙桌子上的循环不太可能充分发挥作用。使用REVERSE和PATINDEX查找第一个非数字,在那里开始SUBSTRING,然后REVERSE结果。没有循环会很慢。

您的示例意味着您也不想匹配空格。

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

最终答案: reverse(substring(reverse(@s),patindex('%[^ 0-9]%',reverse(@s)),1 + len(@s) - patindex('%[^ 0-9]%' ,反向(@s))))

答案 2 :(得分:3)

我相信以下查询快速有用

select reverse(substring(reverse(colA),PATINDEX('%[0-9][a-z]%',reverse(colA))+1,
len(colA)-PATINDEX('%[0-9][a-z]%',reverse(colA))))
from TBLA

答案 3 :(得分:0)

--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))

注意:我在有效的正则表达式匹配中包含了一个短划线。

答案 4 :(得分:-1)

感谢所有非常有帮助的贡献。进一步提取JUST尾随数字:

, 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