2017-06-03 43 views
0

在SQL Server 2014中,如何重寫正則表達式函數來實現下面的輸出?SQL Server 2014提取字符串

ABB_FET_abb_98693989-121966_20170304052411709.csv 

ERP ID = 98693989 
CATALOG ID = 98693989-121966 

在正則表達式,我可以用以下方式獲得ERP IDCatalog id,但如何做同樣的SQL Server?

^.*?_.*?_.*?_(.*?)-(\w+) 
^.*?_.*?_.*?_(.*?)_(\w+) 
+1

[SQL Server的正則表達式(HTTPS的可能重複://計算器。 COM /問題/ 5212665/SQL服務器正則表達式) –

回答

0

你可以嘗試以下解決方案:

DECLARE @Source VARCHAR(100) = 'ABB_FET_abb_98693989-121966_20170304052411709.csv' 

SELECT * 
FROM (VALUES (CONVERT(XML, N'<root><i>' + REPLACE(@Source, N'_', N'</i><i>') + N'</i></root>'))) AS x(XmlCol) 
CROSS APPLY (
    SELECT x.XmlCol.value('(root/i)[4]', 'VARCHAR(25)') 
) AS y(CATALOG_ID) 
CROSS APPLY (
    SELECT LEFT(y.Catalog_ID, CHARINDEX('-', Catalog_ID) - 1)  
) z (ERP_ID) 

注: [1] CONVERT(XML, ...)將源字符串轉換成XML-- <root><i>ABB</i><i>FET</i><i>abb</i><i>98693989-121966</i><i>20170304052411709.csv</i></root>

[2]接下來,我們可以考慮這個XML作爲<i>元素的數組,像其他任何數組一樣,我們可以通過使用索引(基於1)訪問一個項目:(root/i)[4]。結果是'98693989-121966'(參見CROSS APLLY (...) y)。

[3]最後一步是使用LEFT(..., CHARINDEX('-', ...)-1)提取ERP_ID

[4]首先假定源字符串不包含一些XML保留字符(例如<)。第二個假設是源字符串有以下模式:String1_String2_String3_String4...etc...String4包括-字符。

Demo

0

我想在你的情況下,使用REVERSE()可以讓更多像這樣的感覺:

declare @t nvarchar(max) = 'ABB_FET_abb_98693989-121966_20170304052411709.csv'; 
      -- my points:   ^   ^
select SUBSTRING(@t, 
                  -- start cutting 
    LEN(@t) -            -- from end of text by 
    CHARINDEX('_', REVERSE(@t),       -- trying to find first '_' char but 
       PATINDEX('%[-_]%', REVERSE(@t)) + 1) + 2, -- after first '-' or '_' char 
                  -- finish cutting by length of those 
    CHARINDEX('_', REVERSE(@t), 
       PATINDEX('%[-_]%', REVERSE(@t)) + 1) -  
    PATINDEX('%[-_]%', REVERSE(@t)) - 1); 
0

還有另一個選擇:

使用在演唱會幾乎所有的解析/分割函數CROSS APPLY將會做

Declare @YourTable table (ID int,SomeCol varchar(500)) 
Insert Into @YourTable values 
(1,'ABB_FET_abb_98693989-121966_20170304052411709.csv') 
,(2,'XXX_YYY_zzz_12345678-123456_20170304052411709.csv') 

Select A.ID 
     ,[ERP ID]  = left(B.RetVal,charindex('-',B.RetVal)-1) 
     ,[CATALOG ID] = B.RetVal 
From @YourTable A 
Cross Apply (Select * from [dbo].[udf-Str-Parse-8K](A.SomeCol,'_') Where RetVal like '%-%') B 

返回

ID ERP ID  CATALOG ID 
1 98693989 98693989-121966 
2 12345678 12345678-123456 

分析函數,如果有興趣的二手

CREATE FUNCTION [dbo].[udf-Str-Parse-8K] (@String varchar(max),@Delimiter varchar(25)) 
Returns Table 
As 
Return ( 
    with cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)), 
      cte2(N) As (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 a,cte1 b,cte1 c,cte1 d) A), 
      cte3(N) As (Select 1 Union All Select t.N+DataLength(@Delimiter) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter)) = @Delimiter), 
      cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter,@String,s.N),0)-S.N,8000) From cte3 S) 

    Select RetSeq = Row_Number() over (Order By A.N) 
      ,RetVal = LTrim(RTrim(Substring(@String, A.N, A.L))) 
    From cte4 A 
); 
--Orginal Source http://www.sqlservercentral.com/articles/Tally+Table/72993/ 
--Select * from [dbo].[udf-Str-Parse-8K]('Dog,Cat,House,Car',',') 
--Select * from [dbo].[udf-Str-Parse-8K]('John||Cappelletti||was||here','||')