【问题标题】:SQL Regex number not followed by a stringSQL 正则表达式数字后面没有字符串
【发布时间】:2018-07-07 16:48:55
【问题描述】:

让我首先提到这是一个很好讨论的问题,我已经经历了几个线程,包括这两个 - 最接近匹配 Regex to match a string not followed by some stringA regex to match a substring that isn't followed by a certain other substring 但他们没有解决我的问题。

我有包含以下几种不同格式的数量和数量的字符串,例如6 X 200ml 表示 6 包,每包 200 毫升。在这个例子中我只想提取像 6 这样的数量

示例

  1. blah 6 X 200ml -- 6
  2. blah 200 mlX 6 -- 6
  3. blah x 5000 ml -- 0 或更好 1
  4. blah x 500000ml -- 0 或更好 1
  5. 等等 5mlX10 -- 10
  6. blah 500 mlX 10 -- 10

这是我迄今为止尝试过的,但没有任何成功

(X\s*\d+|\d+\s*X)(?!\s*ml)

它也匹配不应该匹配的 case #3 和 4。我也可以用乘号提取像 6 这样的数量,例如 6 X 而不是 6。我可以替换它。

【问题讨论】:

  • 不会this 工作
  • 不。例如,当我包含一个否定的 loo-ahead 时,我会收到以下错误。错误:重复运算符之前的正则表达式无效。解析正则表达式片段时出错:'*(\d)\b(?>>>HERE>>>!\s+ml)) ...
  • 您的数据库是什么(Oracle、MySql、PostgreSQL、MSSQL)? REGEXP 支持在不同的数据库中是不同的,在许多数据库中它是有限的并且不支持许多功能,例如环视。很难不知道您使用的是哪个数据库。
  • 它的 Amazon Redshift 并且由于 redshift 使用 PostgreSQL,如果它可以在 Postgres 上运行,它可能会在 Redshift 上运行
  • @Gurman 为什么要删除你的答案,这是一个很好的答案,只是我的错误没有提到它是一个 SQL 问题。可能您的回答会对其他人有所帮助

标签: sql regex amazon-redshift regex-negation regex-lookarounds


【解决方案1】:

您没有在问题中提及您正在使用的数据库。
SQL 标准不包含正则表达式,因此每个数据库都有自己的正则表达式引擎实现,每个都不同,并且不支持正则表达式的许多功能,例如环视。如果不知道您正在使用的确切数据库,很难为您提供帮助。


下面是两个简单的例子,如何在 Oracle 和 PostgreSQL 数据库中使用
解决这个问题 但这不适用于 Oracle/PostgreSQL 以外的其他数据库



对 Oracle 的查询:
在线演示:http://sqlfiddle.com/#!4/599c41/5

select t.*,
     regexp_substr( regexp_replace( "text", '\d+\s*ml', '///' ), '\d+' ) as x
from table1 t;

|              text |      X |
|-------------------|--------|
|  blah 6 X 200ml   |      6 |
|  blah 200 mlX 6   |      6 |
|  blah x 5000 ml   | (null) |
| blah x 500000ml   | (null) |
|     blah 5mlX10   |     10 |
| blah 500 mlX 10   |     10 |

如果你想用 0 或 1 替换 NULL,你可以这样使用 CASE EXPRESSIONs:

select t.*,
     CASE WHEN regexp_substr( regexp_replace( "text", '\d+\s*ml', '///' ), '\d+' )
        IS NULL THEN '1' /* or 0 */
        ELSE regexp_substr( regexp_replace( "text", '\d+\s*ml', '///' ), '\d+' )
     END as x
from table1 t;

|              text |  X |
|-------------------|----|
|  blah 6 X 200ml   |  6 |
|  blah 200 mlX 6   |  6 |
|  blah x 5000 ml   |  1 |
| blah x 500000ml   |  1 |
|     blah 5mlX10   | 10 |
| blah 500 mlX 10   | 10 |

对 PostgreSQL 的查询:

select t.*,
     substring( regexp_replace( "text", '\d+\s*ml', '///') from '\d+' ) as x
from table1 t;

|              text |      x |
|-------------------|--------|
|  blah 6 X 200ml   |      6 |
|  blah 200 mlX 6   |      6 |
|  blah x 5000 ml   | (null) |
| blah x 500000ml   | (null) |
|     blah 5mlX10   |     10 |
| blah 500 mlX 10   |     10 |

在线演示:http://sqlfiddle.com/#!17/b003b/1

【讨论】:

  • 如果我更改输入,您还能帮我找出解决方案吗?如果最后没有像“ml”这样的单位怎么办?例如 'blah X 200' 应该返回 0 或 null,因为没有提到数量。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-31
  • 2019-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多