我有以下字符串:
Hello World (111)
Welcome to the World (GI 135) (222)
Another Hello World String (ID 12) (141) (333)
我需要解析最后一个括号中的值,因此输出为:
111
222
333
我不知道如何动态地使它总是得到最后括号的charindex / patindex。这就是我到目前为止所做的:
DECLARE @str TABLE ( varString VARCHAR(100) );
INSERT INTO @str
( varString )
VALUES ( 'Hello World (111)' ),
( 'Welcome to the World (GI 135) (222)' ),
( 'Another Hello World String (ID 12) (141) (333)' );
SELECT varString
,Parsed = CASE WHEN PATINDEX('%[0-9])%', varString) - PATINDEX('%([0-9]%', varString) > 0 THEN SUBSTRING(varString, PATINDEX('%([0-9]%', varString) + 1, PATINDEX('%[0-9])%', varString) - PATINDEX('%([0-9]%', varString))
ELSE NULL
END
FROM @str;
但它仅适用于第一种情况Hello World (111)
。
答案 0 :(得分:0)
没关系。我有它。
SELECT varString
,Parsed = REVERSE(SUBSTRING(REVERSE(varString), 2, CHARINDEX('(', REVERSE(varString)) - 2))
FROM @str;
但是如果基于查找最后一个charindex的出现有任何其他解决方案,我将很高兴,如果你分享它。
答案 1 :(得分:0)
您可以使用反向并获取最新信息,如下所示:
Select *, Replace(substring(txt,len(txt) - charindex('(', Reverse(txt))+2, len(txt)), ')', '')
from #yourtext
答案 2 :(得分:0)
将字符串作为xml处理可能是获取最后一个的另一个解决方案,基本上用标签替换括号,强制转换为xml并获取最后一个元素:
select cast(replace(replace(varstring,'(','<n>'),')','</n>') as xml).query('//n[last()]/text()')
答案 3 :(得分:0)
您发布的解决方案要求字符串以右括号结束,即使尾随空格也会将其终止。
XML解决方案非常出色(使用last()函数@Jayvee),但通过添加或减去单个右括号或左括号可以轻松实现。
以下两个解决方案将起作用,并且可以由想要检索的人员轻松修改,第一个数字组或所有数字组。第一个解决方案使用PatterSplitCM,第二个解决方案使用NGrams8K。更新了以下两个示例数据和解决方案。
DECLARE @str TABLE (stringId int identity, varString VARCHAR(100) );
INSERT INTO @str(varstring)
VALUES ( 'Hello World (111)' ),
( 'Welcome to the World (GI 135) (222)' ),
( 'Another Hello World String (ID 12) (141) (333)' ),
( 'Hello World (55555).' ), -- added a period (.)
( 'Welcome to the World (GI 135) (999) and smile (:' ), -- add unclosed parentheses,
( 'Another Hello World String (ID 1212) (14111) (33333)) ' ), -- ends with a space
('No numbers here. Sorry.')
-- SOLUTION #1 (using PatternSplitCM)
SELECT stringId, varString, item
FROM
(
SELECT stringId, varString, item,
rn = ROW_NUMBER() OVER (PARTITION BY varstring ORDER BY itemnumber DESC)
FROM @str
CROSS APPLY dbo.PatternSplitCM(varString, '[0-9]')
WHERE [Matched] = 1
) x
WHERE rn = 1
--ORDER BY stringId;
;
-- SOLUTION #2 (using NGrams8K)
SELECT stringId, varString, item
FROM
(
SELECT stringId, varString,
item = SUBSTRING
(
varString,
position+1,
CHARINDEX(')', varString, position+1)-(position+1)
),
rn = ROW_NUMBER() OVER (PARTITION BY varstring ORDER BY position DESC)
FROM @str
CROSS APPLY dbo.ngrams8k(varString,1)
WHERE token = '('
AND CHARINDEX(')', varString, position+1) > 0 -- exclude strings without closing parenthesis
) x
WHERE rn = 1
每个查询返回:
stringId varString item
--------- ----------------------------------------------------- ----------
1 Hello World (111) 111
2 Welcome to the World (GI 135) (222) 222
3 Another Hello World String (ID 12) (141) (333) 333
4 Hello World (55555). 55555
5 Welcome to the World (GI 135) (999) and smile (: 999
6 Another Hello World String (ID 1212) (14111) (33333)) 33333