在sql中使用正则表达式

时间:2012-03-08 19:05:35

标签: sql sql-server regex

我的表格中有以下行

COL1                       EXTRA         DOUBLE       TEST
12 TEST
123 EXTRA
125 EXTRA 95 DOUBLE
EXTRA 45 99 DOUBLE 

我正在使用正则表达式过滤掉行并将它们适当地移动到不同的列。所以:

  • 对于第一行,我想要提取12并放入TEST列。
  • 对于第二行,我想要提取123并将其放在EXTRA列中。
  • 对于第3行,我想要提取125并将其放在EXTRA列中。
  • 我想忽略95。
  • 对于最后一行,我想要提取45并将其放在EXTRA列中。

我可以通过查询提取值并将它们放在适当的列中,我使用这个正则表达式来提取值:

'%[0-9]%[^A-Z]%[0-9]%'

这个正则表达式的问题是它提取12,但是如果我将正则表达式改为:

它不会从第二行中提取123
'%[0-9]*%[^A-Z]%[0-9]%' 

然后它提取123,但是对于第三行,它将125连接到95,所以我得到12595.有什么方法可以避免95并且只获得125的值?如果我删除了星号,那么它就不会进行任何连接。

任何帮助将不胜感激。我之前发过这个问题,但有些人要求更多解释,所以我发布了一个新问题。

3 个答案:

答案 0 :(得分:1)

假设这是SQL 2005(或者后来我猜...我只能代表2005年),并且COL1数据的所有不同排列都在你的问题中:

UPDATE NameOfYourTable
SET TEST = SUBSTRING(Col1, 0, LEN(Col1) - (LEN(Col1) - PATINDEX('%[0-9] TEST%', Col1) - 1))
WHERE COL1 LIKE '%[0-9] TEST%'

UPDATE NameOfYourTable
SET EXTRA = SUBSTRING(Col1, 0, LEN(Col1) - (LEN(Col1) - PATINDEX('%[0-9] EXTRA%', Col1) - 1))
WHERE COL1 LIKE '%[0-9] EXTRA%'

UPDATE NameOfYourTable
SET EXTRA = SUBSTRING(Col1, PATINDEX('%[0-9]%', Col1), LEN(Col1) - (LEN(Col1) - PATINDEX('%[0-9] [0-9]%', Col1) + LEN('EXTRA ')))'
WHERE COL1 LIKE 'EXTRA [0-9]%'

但不知怎的,我真的不认为这会解决你的问题。我强烈建议您确保通过在某些测试数据上运行它来捕获您需要处理的所有情况。

如果你有很多不同的案例要处理,那么我认为更好的选择是在C#(具有更好的RegExp支持)之类的东西上制作一个小的控制台程序来筛选你的数据并以这种方式应用更新。尝试处理COL1数据的大量排列将成为SQL中的噩梦。

在LIKE,PATINDEX及其(有限的)模式匹配能力上阅读这些内容:

LIKE:http://msdn.microsoft.com/en-us/library/ms179859(v=sql.90).aspx

PATINDEX:http://msdn.microsoft.com/en-us/library/ms188395(v=sql.90).aspx

答案 1 :(得分:1)

我相信你正在寻找的正则表达式如下。这将匹配数字后跟数字,然后忽略任何将来的数字模式。但是,我相信当你使用%regex%regex%...时,它会分别运行每个正则表达式,所以我不确定SQL中正则表达式的细微差别。但是,如果你对rubular.com运行它,它似乎解决了你问的问题。希望它可以在你的正则表达式搜索中有用:)

([0-9]*)([^A-Z])(?>[0-9]*)

然而,我只看了你的第一封信的其他例子,这在这里不起作用。但是,这可能仍然对你有用

答案 2 :(得分:1)

SQL Server本身不支持Regex。它通过Like和Patindex支持一些有限的模式匹配。

如果你真的想在SQL Server中使用Regex,你可以使用像C#这样的.NET语言来创建一个特殊的CLR并将其导入SQL Server,但是它有许多缺点。如果您想使用Regex,更好的方法是让一个在SQL Server上运行的应用程序。该应用程序可以用任何可以连接ODBC的语言编写,如C#或Python,实际上在一篇介绍文章中,我谈到了Python与SQL Server的接口,以便在Simple-Talk上使用正则表达式。

但是,您提供的模式使用SQL Server更有限的模式匹配功能而不是Regex,因此这似乎是您想要的。 Pattern Matching in Search Conditions

上有完整的说明

至于解决你的特定问题,你似乎没有一个特定的模式,而是几个可能的模式。使用单个SQL Server模式几乎不可能处理这种情况,并且正则表达式逻辑也变得不必要地复杂化。所以,如果我在你的位置,我不会尝试创建一个单一的模式,而是一系列的案例,然后根据它提取你需要的数字。