Удалить только ведущие или задние возвраты каретки

Я ошарашен, что этот вопрос уже давно не задавался. Как сделать создание эквивалентной функции в SQL, например LTRIM или RTRIM для возвратов каретки и линейных каналов ТОЛЬКО в начале или конце строки.

Очевидно, REPLACE(REPLACE(@MyString,char(10),''),char(13),'') удаляет ВСЕ возвраты каретки и новые линии. Что НЕ того, что я ищу. Я просто хочу удалить ведущие или конечные.

Ответы

Ответ 1

Найдите первый символ, который не является CHAR(13) или CHAR(10) и вычтите его позицию из длины строки.

LTRIM()

SELECT RIGHT(@MyString,LEN(@MyString)-PATINDEX('%[^'+CHAR(13)+CHAR(10)+']%',@MyString)+1)

RTRIM()

SELECT LEFT(@MyString,LEN(@MyString)-PATINDEX('%[^'+CHAR(13)+CHAR(10)+']%',REVERSE(@MyString))+1)

Ответ 2

Следующие функции - это расширенные типы функций trim вы можете использовать. Скопировано из sqlauthority.com

Эти функции удаляют конечные пробелы, пробелы, пробелы, вкладки, возврат каретки, линейные каналы и т.д.

Обрезать влево

CREATE FUNCTION dbo.LTrimX(@str VARCHAR(MAX)) RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @trimchars VARCHAR(10)
SET @trimchars = CHAR(9)+CHAR(10)+CHAR(13)+CHAR(32)
IF @str LIKE '[' + @trimchars + ']%' SET @str = SUBSTRING(@str, PATINDEX('%[^' + @trimchars + ']%', @str), 8000)
RETURN @str
END

Trim Right

CREATE FUNCTION dbo.RTrimX(@str VARCHAR(MAX)) RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @trimchars VARCHAR(10)
SET @trimchars = CHAR(9)+CHAR(10)+CHAR(13)+CHAR(32)
IF @str LIKE '%[' + @trimchars + ']'
SET @str = REVERSE(dbo.LTrimX(REVERSE(@str)))
RETURN @str
END

Обрезать как влево, так и вправо

CREATE FUNCTION dbo.TrimX(@str VARCHAR(MAX)) RETURNS VARCHAR(MAX)
AS
BEGIN
RETURN dbo.LTrimX(dbo.RTrimX(@str))
END

Использование функции

SELECT dbo.TRIMX(@MyString)

Ответ 3

Вот пример, который вы можете запустить:

Я решил опубликовать результаты как значение Xml, поэтому, когда вы нажмете на него, вы сможете просмотреть возврат каретки.

DECLARE @CRLF Char(2) = (CHAR(0x0D) + CHAR(0x0A))
DECLARE @String VarChar(MAX) = @CRLF + @CRLF + '    Hello' + @CRLF + 'World  ' + @CRLF + @CRLF
--Unmodified String:
SELECT CAST(@String as Xml)[Unmodified]
--Remove Trailing Whitespace (including Spaces).
SELECT CAST(LEFT(@String, LEN(REPLACE(@String, @CRLF, '  '))) as Xml)[RemoveTrailingWhitespace]
--Remove Leading Whitespace (including Spaces).
SELECT CAST(RIGHT(@String, LEN(REVERSE(REPLACE(@String, @CRLF, '  ')))) as Xml)[RemoveLeadingWhitespace]
--Remove Leading & Trailing Whitespace (including Spaces).
SELECT CAST(SUBSTRING(@String, LEN(REPLACE(@String, ' ', '_')) - LEN(REVERSE(REPLACE(@String, @CRLF, '  '))) + 1, LEN(LTRIM(RTRIM(REPLACE(@String, @CRLF, '  '))))) as Xml)[RemoveAllWhitespace]
--Remove Only Leading and Trailing CR/LF (while still preserving all other Whitespace - including Spaces). - 04/06/2016 - MCR.
SELECT CAST(SUBSTRING(@String, PATINDEX('%[^'+CHAR(13)+CHAR(10)+']%',@String), LEN(REPLACE(@String, ' ', '_')) - PATINDEX('%[^'+CHAR(13)+CHAR(10)+']%',@String) + 1 - PATINDEX('%[^'+CHAR(13)+CHAR(10)+']%', REVERSE(@String)) + 1) as Xml)[RemoveLeadingAndTrailingCRLFsOnly]

Не забудьте удалить Cast-to-Xml, так как это было сделано как доказательство концепции, чтобы показать, что оно работает.

Как это лучше, чем принятый в настоящее время ответ?

На первый взгляд это может показаться, что использует больше функций, чем принятый ответ.
Однако, это не так.
Если вы комбинируете оба подхода, перечисленные в Принятом ответе (для удаления пропущенных и ведущих пробелов), вам либо придется сделать два прохода, обновляющих запись, либо скопировать все одну логику в другую (везде @String), что вызовет больше вызовов функций и станет еще труднее читать.

Ответ 4

В SQL Server 2017 вы можете использовать функцию TRIM для удаления определенных символов из начала и конца за один раз:

WITH testdata(str) AS (
    SELECT CHAR(13) + CHAR(10) + ' test ' + CHAR(13) + CHAR(10)
)
SELECT
    str,
    TRIM(CHAR(13) + CHAR(10) + CHAR(9) + ' ' FROM str) AS [trim cr/lf/tab/space],
    TRIM(CHAR(13) + CHAR(10) FROM str) AS [trim cr/lf],
    TRIM(' ' FROM str) AS [trim space]
FROM testdata

Результат:

result - non-printable characters replaced with visible alternates

Обратите внимание, что последний пример (пробел) ничего не делает, как ожидалось, поскольку пробелы находятся посередине.