Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 如何从字符串中删除任何尾随数字?_String_Sql Server 2008_Tsql - Fatal编程技术网

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

String 如何从字符串中删除任何尾随数字?,string,sql-server-2008,tsql,String,Sql Server 2008,Tsql,样本输入: “你好,你好吗?” “纽约的第一家比萨饼店是什么?” “多米诺骨牌是第一” “胡说八道123123” “更多废话12321123132” 预期产出: “你好,你好吗?” “纽约的第一家比萨饼店是什么?” “多米诺骨牌是数字” “废话” “更多废话” 我认为这是一个两步的过程: 将整个字符串按相反的顺序拆分为字符,每个字符一行(包括空格) 循环遍历,如果是空格或数字,则跳过,否则添加到另一个数组的开始 我会得到想要的结果 我可以想出一些快速而肮脏的方法,但这需要执行得相当好,因为它是一

样本输入:

“你好,你好吗?”

“纽约的第一家比萨饼店是什么?”

“多米诺骨牌是第一”

“胡说八道123123”

“更多废话12321123132”

预期产出:

“你好,你好吗?”

“纽约的第一家比萨饼店是什么?”

“多米诺骨牌是数字”

“废话”

“更多废话”

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

  • 将整个字符串按相反的顺序拆分为字符,每个字符一行(包括空格)
  • 循环遍历,如果是空格或数字,则跳过,否则添加到另一个数组的开始
  • 我会得到想要的结果

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

    有什么建议吗

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