我需要获取文本中特定单词的行号和位置(在该行上)。
例如:
--
This is my first line.
This is my second line.
--
如果我要检查“秒”,我应该得到类似“ 2,12
有任何建议吗?
答案 0 :(得分:3)
假设您要查找每行的第一个匹配项,并假设LINE由char(13)而不是标点符号分隔。
示例
Declare @YourTable table (ID int,SomeText varchar(max))
Insert Into @YourTable values
(1,'This is my first line.
This is my second line.')
,(2,'This another but has a second note
Which not related to the prior "second" note')
Declare @Search varchar(100)='second'
Select A.ID
,Position=concat(RetSeq,',',charindex(@Search,RetVal))
From @YourTable A
Cross Apply (
Select RetSeq = row_number() over (order by 1/0)
,RetVal = ltrim(rtrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace((Select replace(replace(SomeText,char(10),''),char(13),'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
) B
Where charindex(@Search,RetVal)>0
返回
ID Position
1 2,12
2 1,24
2 2,33
编辑-请求的编辑
Select Top 1 with Ties
A.ID
,Position=concat(RetSeq,',',charindex(@Search,RetVal))
From @YourTable A
Cross Apply (
Select RetSeq = row_number() over (order by 1/0)
,RetVal = B.i.value('(./text())[1]', 'varchar(max)')
From (Select x = Cast('<x>' + replace((Select replace(replace(SomeText,char(10),''),char(13),'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
) B
Where charindex(@Search,RetVal)>0
Order by Row_Number() over (Partition By ID Order by RetSeq)
返回
ID Position
1 2,12
2 1,24
答案 1 :(得分:0)
这里是不使用子查询的替代解决方案;它依赖于SQL Server string functions,例如Ord
和CHARINDEX
。
REVERSE
原理是首先找到搜索到的字符串(SELECT
CASE WHEN CHARINDEX( @match, t.value ) < CHARINDEX( CHAR(10), t.value )
THEN CONCAT( '1,', CHARINDEX( @match, t.value ) )
ELSE
CONCAT(
LEN(LEFT(t.value, CHARINDEX(@match, t.value)))
- LEN(REPLACE(LEFT(t.value, CHARINDEX(@match, t.value)), CHAR(10), '')) + 1,
',',
CHARINDEX (CHAR(10), REVERSE(LEFT(t.value, CHARINDEX(@match, t.value)))) - 1
)
END
from t;
)的位置,然后计算上一个回车符(@match
的位置-根据情况也可以是CHAR(10)
您的EOF设置),使用CHAR(13)
。有了这两个值,我们就可以计算出匹配在行上的位置以及行号(为此,我们将子字符串的长度比较,直到匹配与其没有回车符的长度为止)。当比赛在第一行时,必须格外小心。
db <>提琴here
REVERSE
| (No column name) | | :--------------- | | 2,12 |