在两个定界符之间替换子字符串,或者直到字符串结尾

时间:2018-11-13 12:36:25

标签: sql sql-server string sql-server-2008

在SQL Server 2008中的过程中,我需要替换2个标识符之间的子字符串。我不知道要替换的完整字符串,或者不存在第二个标识符。

如果没有终止符标识符,则需要将字符串的结尾视为1。另外,标识符可以相同。

DECLARE @startIdenfier VARCHAR(10) = 'the'
DECLARE @endIdenfier   VARCHAR(10) = 'the'
DECLARE @newString     VARCHAR(20) = 'new string that'

样本输入/输出:

“这是需要在其上应用 过程的旧字符串。 ->
“这是需要 过程的新字符串。

'这是 旧字符串'->
“这是 新字符串

SET @endIdenfier = 'I'

“这是我不喜欢的 旧字符串 ”->
“这是我不喜欢的 新字符串

这是一个通用替换,由于REPLACE函数不接受索引,因此我找不到正确的方法。

编辑:该社区很棒。很抱歉,我无法选择多个可接受的解决方案,但感谢大家的帮助。我将尝试所有已发布的解决方案(除了已接受的经过我测试的解决方案),然后分别投票。

5 个答案:

答案 0 :(得分:1)

像这样...

DECLARE @initialString   VARCHAR(32) = '1234567890123456789'
DECLARE @startIdentifier VARCHAR(32) = '34'
DECLARE @endIdentifier   VARCHAR(32) = '34'
DECLARE @newString       VARCHAR(32) = 'ABC'


DECLARE @headChars INT = CHARINDEX(@startIdentifier, @initialString, 1)

IF @headChars > 0
  SET @headChars = @headChars + LEN(@startIdentifier) - 1


DECLARE @bodyChars INT = CHARINDEX(@endIdentifier, @initialString, @headChars + 1)

IF @bodyChars > 0
  SET @bodyChars = LEN(@initialString) - @bodyChars + 1


SELECT
  LEFT(@initialString,  @headChars)
  + @newString
  + RIGHT(@initialString, @bodyChars)

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=b8a179d0e63840dfa60905d9951e4b22

例如...

'1234567890123456789'
  '34'                => Start @ 1 => Found @  3 => keep chars 1->4
            '34'      => Start @ 5 => Found @ 13 => keep chars 13->end

答案 1 :(得分:1)

您可以执行以下操作:

let maiStoryBoard = UIStoryboard(name: "Main", bundle: nil) //Storyboard in which AuthVC lies

let authVC = mainStoryBoard.instantiateViewControllerWithIdentifier("AuthVC") as! AuthVC
 let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
 appDelegate.window?.rootViewController = authVC

答案 2 :(得分:1)

--Find the start index plus the length of the string found (plus one for the space)
SET @startIdx = CHARINDEX(@startIdentifier, @initialString, 1) + LEN(@startIdentifier) + 1

--Find the next occurrence of the end identifier (minus one for the space)
SET @endIdx = CHARINDEX(@endIdentifier, @initialString, @startIdx) - 1;

--end not found?
IF @endIdx = -1 SET @endIdx = LEN(@initialString) + 1;

--Use the STUFF function to remove the old chars from endindex-startindex, and insert the new string at the startindex
SET @results = STUFF(@initialString,  @startIdx, @endIdx - @startIdx, @newString)

完整:

DECLARE @startIdenfier Varchar(10)
SET @startIdenfier = 'the'
DECLARE @endIdenfier Varchar(10)
SET @endIdenfier = 'the'
DECLARE @newString Varchar(100)
SET @newString = 'new string that'

DECLARE @initialString VARCHAR(256) = 'this is the old string that the process needs to be applied on';

DECLARE @startIdx INT;
SET @startIdx = CHARINDEX(@startIdenfier, @initialString, 1) + LEN(@startIdenfier) + 1;

DECLARE @endIdx INT;
SET @endIdx= CHARINDEX(@endIdenfier, @initialString, @startIdx) - 1;
IF @endIdx = -1 SET @endIdx = LEN(@initialString) + 1;

DECLARE @results VARCHAR(256);
SET @results = STUFF(@initialString,  @startIdx, @endIdx - @startIdx, @newString);

SELECT @results

答案 3 :(得分:1)

我认为您将需要合并PATINDEX函数并使用开始和结束标识符来创建模式。这将满足同时存在开始和结束标识符的条件...

DECLARE @OldString nvarchar(max)
DECLARE @NewString nvarchar(max)
DECLARE @StartLocation bigint
DECLARE @Pattern nvarchar(200) = '%' + @StartIdentifier + ' % ' + @EndIdentifer + '%'
SELECT @StartLocation = PATINDEX(@Pattern, 'old complete string')

如果找到了模式,则可以通过在位置(@StartLocation + @StartIdentifier的长度+ 1)处对“旧完整字符串”进行子字符串替换来替换该字符串。若要确定SUBSTRING的长度,您需要使用(@StartLocation + @StartIdentifier的长度+ 1)开始的旧完整字符串的CHARINDEX定位@EndIdentifier的位置。从CHARINDEX的结果中减去@StartLocation + StartIdentifier的长度+ 1。

SELECT @OldString = SUBSTRING('complete old string', @StartLocation + LEN(@StartIdentifier) + 1, CHARINDEX(' ' + @EndIdentifier, 'old complete string', @StartLocation + LEN(@StartIdentifier) + 1) - (@StartLocation + LEN(@StartIdentifier) + 1)))

这时您可以直接进行替换以获取新字符串。

SELECT @NewCompleteString = REPLACE('old complete string', @OldString, @NewString)
  

”如果没有“终止符”标识符,则需要以   字符串视为一个。”

如果未找到初始模式,我们将退回到仅搜索@StartIdentifier的位置。为此,您可以将模式重置为仅包含@StartIdentifier ...

SELECT @Pattern = '%' + @StartIdentifier + ' %'
SELECT @StartLocation = PATINDEX(@Pattern, 'old complete string')

如果找到了模式,则可以从(@StartLocation + @StartIdentifier的长度+ 1)开始,以SUBSTRING替换旧字符串,长度为“旧完整字符串”长度-(@StartLocation +长度为@StartIdentifier +1)...

SELECT @OldString = SUBSTRING('old complete string', @StartLocation + LEN(@StartIdentifier) + 1, LEN('old complete string') - (@StartLocation + LEN(@StartIdentifier) + 1))

然后您可以替换...

SELECT @NewCompleteString = REPLACE('old complete string', @OldString, @NewString)

答案 4 :(得分:1)

只需使用STUFFCHARINDEX。找出答案:

  • 替换开始的位置(the的位置+ the的长度)
  • 替换结束的位置(the的位置从上方开始)

减去位置以计算要替换的字符数。

DECLARE @string VARCHAR(100) = 'This is the old string that the process needs to be applied on.'
DECLARE @replace VARCHAR(100) = 'NEW STRING THAT '
DECLARE @delim1 VARCHAR(100) = 'the '
DECLARE @delim2 VARCHAR(100) = 'the '

DECLARE @pos1 INT = CHARINDEX(@delim1, @string) + DATALENGTH(@delim1)
DECLARE @pos2 INT = ISNULL(NULLIF(CHARINDEX(@delim2, @string, @pos1), 0), DATALENGTH(@string) + 1)

SELECT STUFF(@string, @pos1, @pos2 - @pos1, @replace)

-- "This is the NEW STRING THAT the process needs to be applied on."

SET @delim2 = 'xxx'
SET @pos1 = CHARINDEX(@delim1, @string) + DATALENGTH(@delim1)
SET @pos2 = ISNULL(NULLIF(CHARINDEX(@delim2, @string, @pos1), 0), DATALENGTH(@string) + 1)

SELECT STUFF(@string, @pos1, @pos2 - @pos1, @replace)

-- "This is the NEW STRING THAT "

注意:空格应该是搜索定界符的一部分,而不是逻辑。 the不匹配them and threfore