【问题标题】:How to get text between two words/characters如何在两个单词/字符之间获取文本
【发布时间】:2017-01-07 15:39:51
【问题描述】:

如何在两个已知单词之间获取一些文本?

子选择示例:

(SELECT TOP(1)Note
FROM Clients
WHERE (ID=@ID) AND (Note IS NOT NULL) AND (Note NOT LIKE '%Damaged%')) AS Note

这会返回:

Blablabla bla bla blabla bla bla bla (21.08.2015) "some text" word bla bla
Blablabla bla bla blabla bla bla bla (25.08.2015) "another text" word bla bla 
Blablabla bla bla blabla bla bla bla (28.08.2015) "TEXT I NEED TO GET" word bla bla blabla bla bla.

所以我需要在最后一个“)”和最后一个“单词”之间获取文本

尝试了一些魔法,但它不适用于最后一个“)”和最后一个“单词”

【问题讨论】:

  • 您使用的是 MS SQL Server 吗? (顶部...)
  • 是的标准 SQL 服务器,没有 MySQL 也没有 Oracle。
  • 标准 SQL(即 ANSI SQL) SQL Server.
  • 转至 here 并对您的查询进行排序
  • 试过了,但没有找到如何只在最后一个单词之间获取文本。

标签: sql-server


【解决方案1】:

可能是这样的:

你试图找到最后一次出现。这是还原字符串中的第一个...

--这是一个用来放置字符串的表格模型:

DECLARE @tbl TABLE(YourLine VARCHAR(100));
INSERT INTO @tbl VALUES
 ('Blablabla bla bla blabla bla bla bla (21.08.2015) "some text" word bla bla')
,('Blablabla bla bla blabla bla bla bla (25.08.2015) "another text" word bla bla') 
,('Blablabla bla bla blabla bla bla bla (28.08.2015) "TEXT I NEED TO GET" word bla bla blabla bla bla.');

--这里我指定你要搜索的词

DECLARE @SearchWord VARCHAR(100)='word';

--这是查询

SELECT REVERSE(C.CutOut) AS YourSnippet
FROM @tbl AS tbl

--CROSS APPLY 按行工作:取​​当前行并还原它!

CROSS APPLY(SELECT REVERSE(tbl.YourLine) AS RevLine) AS A

--找到)第一次次出现和reverted searchword第一次次出现!

CROSS APPLY(SELECT CHARINDEX(')',A.RevLine) AS PosParanthesis
                  ,CHARINDEX(REVERSE(@SearchWord),A.RevLine) AS PosWord) AS B 

--将找到的位置的字符串剪切到计算出的长度

CROSS APPLY(SELECT SUBSTRING(A.RevLine,B.PosWord + LEN(@SearchWord)+1,B.PosParanthesis-B.PosWord-LEN(@SearchWord)-1) AS CutOut) AS C

las CROSS APPLY 的结果是您的目标字符串,但相反。因此,在主SELECT 中的最后一个反转...

【讨论】:

  • SUBSTRING 中的 +1 和 -1 删除了结果中 'word' 之后的空格。您可能会争辩说应该包含这个空格,从而删除 +1 和 -1。这将使 @SearchWord = 'ord' 的结果包含 w.
  • 看起来好复杂。
  • 嗨@J.Adam,这一点都不复杂......关键是我关于字符串反转的第二行。 REVERSE('hello') 返回olleh。查看我的编辑
  • 感谢您的回复。但我找到了“更简单”的方法。
【解决方案2】:
declare @start varchar(100)
set @start = 'startword'

declare @end varchar(100)
set @end = 'endword'

SELECT TOP(1) Note , substring( LEFT(note, charindex(@end, note, CHARINDEX(@start, note))-1), CHARINDEX(@start, note) + len(@start), LEN(note))   result
FROM Clients
WHERE (ID=@ID) AND (Note IS NOT NULL) 

【讨论】:

  • 看起来不错,但它只返回我在#start 和#end 之间的文本的第一种情况。我怎样才能得到最后一个?
  • last 表示结束词?
  • 我需要的文本在最后一个“)”和最后一个“单词”之间。您的查询返回第一个“)”和第一个“单词”之间的文本。如果您仅更改结束词,它将返回最后一个“单词”和拳头“)”之间的所有内容,对吗?但我也注意到只有一个“)”和一个“单词”。但是什么时候有更多,仍然需要最后一个。
【解决方案3】:
CREATE FUNCTION [dbo].[fnSplitString] 
( 
    @string NVARCHAR(MAX),
    @id int , ,
    @sword varchar(30) ,
    @delimiter varchar(30) 
) 
RETURNS @output TABLE(splitdata NVARCHAR(MAX) , id int
) 
BEGIN 
    DECLARE @start INT, @end INT 
    declare @start1 varchar(100)
    set @start1 = @sword

    declare @end1 varchar(100)
    set @end1 =  @delimiter
    SELECT @start = 1, @end = CHARINDEX(@delimiter, @string) + Len(@delimiter) - 1
    WHILE @start < LEN(@string) + 1 BEGIN 
        IF @end = 0  
            SET @end = LEN(@string) + 1

        INSERT INTO @output (splitdata , id)  
        VALUES(substring( LEFT((SUBSTRING(@string, @start, @end - @start)), charindex(@end1, (SUBSTRING(@string, @start, @end - @start)), CHARINDEX(@start1, (SUBSTRING(@string, @start, @end - @start))))-1), CHARINDEX(@start1, (SUBSTRING(@string, @start, @end - @start))) + len(@start1), LEN((SUBSTRING(@string, @start, @end - @start))))  ,@id ) 

        SET @start = @end + 1 
        SET @end = CHARINDEX(@delimiter, @string, @start)+ Len(@delimiter) - 1
         END 
    RETURN 
END

Select note , fnSplitString (note , id ,'startword', 'endword') from clients 

【讨论】:

  • 我创建了一个函数,它应该使用结束词分割你的字符串,然后尝试在第一个和最后一个之间取值。看看它是否适合你。谢谢
  • 这是程序化思维的一种复杂方式。你真的应该避免不需要它们的循环......
  • 感谢您的回复。但我找到了“更简单”的方法。
【解决方案4】:

伙计们,我找到了自己的解决方案:

DECLARE @S VARCHAR(MAX) = '布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉 (21.08.2015) “一些文字”字 bla bla Blablabla bla bla blabla bla bla bla (25.08.2015) “另一个文本”字 bla bla Blablabla bla bla blabla bla bla bla (28.08.2015) “我需要得到的文字” word bla bla blabla bla 废话。'

SELECT LEFT(REVERSE(LEFT(REVERSE(@S), CHARINDEX(')', REVERSE(@S)) - 2))+'word', CHARINDEX('word',REVERSE(LEFT(REVERSE(@S), CHARINDEX(')', REVERSE(@S)) - 2))+'word')-1) 作为回应

这完全返回:

“我需要获取的文本”

感谢大家带领我走到这一步。

【讨论】:

  • 您好,您的简单解决方案与我的完全一样。最重要的区别是,您重复使用相同的函数调用。我使用 CROSS APPLY 的方法是 - 至少在我看来 - 更容易阅读,因为当你有一个深度嵌套的 函数时,中间结果与 name 一起使用-in-function-in-repeated-function 代码。您使用两次LEFT 而我使用SUBSTRING 并计算长度。你认为容易是个人意见。我不想在几个月内维持你的功能:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
  • 2020-12-30
  • 2019-10-10
相关资源
最近更新 更多