【发布时间】:2025-12-21 02:50:09
【问题描述】:
我需要将字符串拆分为特定单词边界的行。问题是我需要维护触发拆分的特定单词边界,因为稍后我想重新组合行并查看分隔符。我正在更新一个看起来像这样的现有函数:
DECLARE @Input VARCHAR(8000) = 'AC/DC, The Quick, Brown Fox'
DECLARE @Delimiters varchar(100) = '%[ ,-/]%'
;WITH
[Elements] AS
(
SELECT
1 AS Position
, 1 AS StartOffset
, PATINDEX(@Delimiters, @Input) - 1 AS EndOffset
, @Input AS Input
, SUBSTRING(@Input, 1, ISNULL(NULLIF(PATINDEX(@Delimiters, @Input), 0) - 1, 8000)) AS Word
UNION ALL
SELECT
Position + 1 AS Position
, EndOffset + 2 AS StartOffset
, EndOffset + ISNULL(NULLIF(PATINDEX(@Delimiters, SUBSTRING(Input, EndOffset + 2, 8000)), 0), LEN(@Input) - EndOffset) AS EndOffset
, Input
, SUBSTRING(Input, EndOffset + 2, ISNULL(NULLIF(PATINDEX(@Delimiters, SUBSTRING(Input, EndOffset + 2, 8000)), 0) - 1, 8000)) AS Word
FROM
[Elements]
WHERE
EndOffset BETWEEN 1 AND LEN(@Input) - 1
)
SELECT
*
FROM
[Elements]
给我:
+----------+-------------+-----------+-----------------------------+-------+
| Position | StartOffset | EndOffset | Input | Word |
+----------+-------------+-----------+-----------------------------+-------+
| 1 | 1 | 2 | AC/DC, The Quick, Brown Fox | AC |
| 2 | 4 | 5 | AC/DC, The Quick, Brown Fox | DC |
| 3 | 7 | 6 | AC/DC, The Quick, Brown Fox | |
| 4 | 8 | 10 | AC/DC, The Quick, Brown Fox | The |
| 5 | 12 | 16 | AC/DC, The Quick, Brown Fox | Quick |
| 6 | 18 | 17 | AC/DC, The Quick, Brown Fox | |
| 7 | 19 | 23 | AC/DC, The Quick, Brown Fox | Brown |
| 8 | 25 | 27 | AC/DC, The Quick, Brown Fox | Fox |
+----------+-------------+-----------+-----------------------------+-------+
这很好地分解了它,但从结果集中省略了“/”和“,”行。我确实有一个可以碰到的数字表,而且我对如何实现这一点非常灵活。
我可以通过循环蛮力通过它,但这似乎太野蛮了。
【问题讨论】:
-
请不要朝这个方向吐痰……
-
您的拆分逻辑不能很好地处理两个分隔符。您最好将整个事情分解(您可以使用数字表),检查每个字符是否是分隔符,然后构建类似于当前逻辑的单词。
-
@JNK 你能提供一个使用数字表对已知分隔符列表进行拆分的示例吗?
-
@JohnHurrell 他们到处都是(搜索字符串拆分 SQL 数字表),但基本思想是使用数字表有效地索引到字符串的每个字符。
-
@JNK:无论如何,谢谢,但我所知道的所有示例都使用数字表对单个逗号分隔符拆分字符串。我现在正在通过使用一些逻辑来修改我需要做的事情,其中字符在一个位置 NOT LIKE '[a-z]' 希望我可以避免必须指定大量的分隔符。
标签: sql-server