【问题标题】:LIKE pattern T-SQLLIKE 模式 T-SQL
【发布时间】:2015-09-27 20:59:24
【问题描述】:

我写了一个短语,它将一个很长的字符串分成小段,在完成一个项目的短语后,它将他从@input中删除并继续,直到它无法找到任何要短语的项目。 我正在根据 LIKE 模式选择项目。

在某些情况下,它会选择消息的其他部分,然后以不定式循环结束。

我希望使用 LIKE 子句选择的模式格式为:

(从 1 到 9 的任何数字)+(仅可变长度 A-Z)+ '/' + (仅可变长度 A-Z)+Cr 或 Lf 或 CrLf 的空格。

--This is what I do have: 
DECLARE @match NVarChar(100)
    SET @match  =  '%[1-9][a-z]%'

DECLARE @input1 varchar(max),@input2 varchar(max)  
    SET @input1 ='1ABCD/EFGH *W/17001588 *RHELLO SMVML1C'

DECLARE @position Int 
    SET @position = PATINDEX(@match, @input1);

SELECT @position;

--after the loop- it is also 'catching' the 1C at the end of the string: 

SET @input2     = '*W/17001588 *RHELLO SMVML1C'
SET @position   = PATINDEX(@match, @input2);

SELECT @position

---In order to eliminate this, I have tried to change @match:

SET @match  =  '%[1-9][a-z][/][a-z]%'

SET @position = PATINDEX(@match, @input1);
SELECT @position  --postion is  0, so the first item, that should have been selected, wasn't selected
SET @position   = PATINDEX(@match, @input2);
SELECT @position --postion is  0

非常感谢您的帮助!

【问题讨论】:

  • T-SQL 没有正则表达式或任何其他内置模式匹配器可以满足您的需求。特别是“任意数量”和“可变长度”部分会导致问题。
  • 那么在你的新比赛中,@input1@position 应该是 1,@input2@position 应该是 0?对吗?
  • 您无法使用 PATINDEX 的有限功能解析此类输入。您应该在代码中使用正则表达式或编写一个实际的解析器。
  • 您是否考虑过使用其他工具?
  • 使用 CLR 和正则表达式 [\d][A-Z]+/[A-Z]+[ \r\n] 这很简单。

标签: sql-server tsql sql-server-2012 sql-like


【解决方案1】:

尝试将匹配变量/条件更改为:

SET @match  =  '%[1-9][a-z]%[/][a-z]%'

这将为您提供所需的结果。粗略地翻译它是说“给我第一个匹配的起始位置,其中模式是 [anything]-[number from 1-9]-[single letter from az]-[anything]-[slash]-[single letter from az]-[任何东西]。
希望这会有所帮助!

【讨论】:

  • 不幸的是,这与他搜索的可变长度部分不匹配,1a/a 匹配 1abc/def 不匹配。也不匹配终端字符。
  • 实际上它在 1abc/def 上匹配......这就是第二个通配符的处理方式。自从我给出答案后,问题也发生了变化(最初没有终端字符,也不是斜杠 A-Z 之前的字符串)
【解决方案2】:

我同意上面的 cmets;这是一个正则表达式问题,需要使用正则表达式工具来解决。我会推荐 SimpleTalk 创建的程序集。 You can get their code and read their very thorough article.

不幸的是,此解决方案需要对数据库和服务器具有严格的管理员权限,因此它不能作为脚本移植。但我认为,如果您定期在同一个数据库上开发,这些功能值得付出任何努力来安装。

请注意,正则表达式是一个真正的处理猪,会破坏 SQL Server 中的大部分索引效率。只有当你不能使用like时才使用它。

【讨论】:

    【解决方案3】:

    我不知道这是否解决了您的整个问题,但如果您可以在输入前加上空格,则可以修改模式以避免匹配没有前面空格的数字。

    set @input = ' '+@input;
    set @match = '% [1-9][a-z]%';
    

    如果您需要您的模式来解释 Cr 和 Lf 等其他空格,您的模式可能如下所示:

    set @match = '%[ '+char(13)+char(10)+'][1-9][a-z]%';
    

    【讨论】:

      猜你喜欢
      • 2011-11-02
      • 2011-03-16
      • 1970-01-01
      • 2020-10-28
      • 1970-01-01
      • 2013-10-30
      • 1970-01-01
      • 2012-12-23
      • 1970-01-01
      相关资源
      最近更新 更多