与TSQL模式匹配

时间:2014-10-23 21:18:24

标签: sql sql-server tsql

需要查找符合以下条件的列。

  • 必须从" Foo"开始
  • 跟随任意长度
  • 请使用空格或" - "
  • 跟随任意长度
  • 结束或跟随A,B,C,PE,句号或空格

所以以下内容匹配

  • Foo42004 45058
  • Foo42004-45058
  • Foo42004 45058A
  • Foo42004 45058PE
  • Foo42004 45058B.v34
  • Foo42004-45058C bar
  • Foo42004-45058C bar

select语句类似于以下内容,但我认为它不起作用

    select mycolumn 
    from mytable 
    where mycolumn like 'Foo[0-9]{0,15}[ -][0-9]{0,15}[A|B|C|PE]%' 

3 个答案:

答案 0 :(得分:2)

实现这一点的最快方法是使用CLR实现真正的正则表达式函数。谷歌搜索" sql clr regex"有很多免费选项可用。以及如何推销自己的说明。

您的另一个选择是使用T-SQL string parsing functions来验证格式,从而构建自己的函数。

答案 1 :(得分:1)

TSQL在Regex中没有像{0,15}那样的概念。因此,模式Foo [0-9] {0,15}的部分将匹配字符串Foo0 {0,15},Foo1 {0,15},Foo2 {0,15},... Foo9 {0,15像BlorgBeard说的那样,LIKE是有限的。

答案 2 :(得分:0)

一个非常hacky的解决方案,利用patindex的几乎正则表达式功能:

select mycolumn 
from
(
    select mycolumn 
    , StartsFoo
    , case when patindex('%[^0-9]%',foo2)=0 and LEN(foo2) between 0 and 15 then 1 else 0 end HasZeroToFifteenDigits
    , SUBSTRING(foo3,patindex('%[^0-9]%',foo3 + 'x')+1,LEN(foo3)) foo4
    from
    (
        select mycolumn 
        , case when mycolumn  like 'Foo%' then 1 else 0 end StartsFoo
        , SUBSTRING(mycolumn ,4,case when patindex('%[- ]%',mycolumn )<4 then 0 else patindex('%[- ]%',mycolumn )-4 end) foo2
        , SUBSTRING(mycolumn ,case when patindex('%[- ]%',mycolumn )<0 then 0 else patindex('%[- ]%',mycolumn )+1 end,LEN(mycolumn )) foo3
        from mytable 
    ) x
) y
where StartsFoo * HasZeroToFifteenDigits * case when LEN(foo4)=0 or patindex('[A|B|C|PE|.| ]%',foo4)=1  then 1 else 0 end = 1

演示代码:

declare @a table(foo nvarchar(32), shouldMatch bit)
insert @a
select 'Foo42004 45058', 1
union select 'Foo42004-45058', 1
union select 'Foo42004 45058A', 1
union select 'Foo42004 45058PE', 1
union select 'Foo42004 45058B.v34', 1
union select 'Foo42004-45058C bar', 1
union select 'Foo42004-45058C bar', 1
union select 'Goo42004-45058', 0
union select 'Foo42004x45058', 0
union select 'Foo42x04 45058', 0

select foo
, shouldMatch
, StartsFoo * HasZeroToFifteenDigits * case when LEN(foo4)=0 or patindex('[A|B|C|PE|.| ]%',foo4)=1  then 1 else 0 end doesMatch
from
(
    select foo
    , shouldMatch
    , StartsFoo
    , case when patindex('%[^0-9]%',foo2)=0 and LEN(foo2) between 0 and 15 then 1 else 0 end HasZeroToFifteenDigits
    , SUBSTRING(foo3,patindex('%[^0-9]%',foo3 + 'x')+1,LEN(foo3)) foo4
    from
    (
        select foo, shouldMatch
        , case when foo like 'Foo%' then 1 else 0 end StartsFoo
        , SUBSTRING(foo,4,case when patindex('%[- ]%',foo)<4 then 0 else patindex('%[- ]%',foo)-4 end) foo2
        , SUBSTRING(foo,case when patindex('%[- ]%',foo)<0 then 0 else patindex('%[- ]%',foo)+1 end,LEN(foo)) foo3
        from @a 
    ) x
) y

SQL小提琴:http://sqlfiddle.com/#!6/d41d8/22453