从PCRE REGEXP转换为MySQL REGEXP_REPLACE

问题描述

我正在尝试提取字符串的音量以对其进行数字排序。


给出以下数据:

  1. 300毫升的东西
  2. 300毫升的东西
  3. 特殊事物(300毫升)
  4. 8-v不匹配的内容

首次尝试: 只需将字符串转换unsigned(在此线程中找到:reference

问题:显然,它还会考虑第四个数据示例。


第二次尝试:使用REGEXP_REPLACE提取值(在此线程中找到:reference

CAST(
    REGEXP_REPLACE(
        LOWER(column),"[:digit:]+[:space:]*ml","///"
    ) as UNSIGNED
) AS volume

...使用manual中定义的character_class

问题character_class似乎无法按预期工作(可能是字符类名称出现空格的问题?)。


第三次尝试:使用通用的Regexp令牌

CAST(
    REGEXP_REPLACE(
        LOWER(column),"\d+\s*ml","///"
    ) as UNSIGNED
) AS volume

...看起来更好。

问题:它也再次与第4个数据示例匹配。


问题:我如何在MysqL REGEXP_REPLACE中执行某种正向查找,该正向查找仅与数据示例1-3匹配(忽略由于转换为较低而导致的区分大小写)?

我尝试过的方法似乎在PCRE(带有全局标志)中工作正常,但在MysqL中却不行:

^.*\d+\s*ml.*$(忽略丢失的捕获组)

翻译如下:匹配所有内容,直到1个或多个数字,然后是0个或多个空格,然后找到字符串ml

解决方法

尝试一下:

       CAST(
          REGEXP_SUBSTR( 
                LOWER(@c),"([[:digit:]]+)[[:space:]]*ml" )
          AS UNSIGNED)  AS VOLUME;

您绝对希望使用REGEX_SUBSTR()而不是REGEX_REPLACE()。

我已经在MySQL 8和MariaDB 10.3-10.5上进行了尝试。无论如何,对我来说,都需要将括号[[:digit:]]加倍。而且,如果您使用旧的\s表示法,则需要将\转义符加倍:\\s+

({MariaDb's implementation of REGEX_SUBSTR()不接受optional parameters that MySQL's does

我不得不说,在医疗卫生IT部门工作过,将正则表达式与药物剂量结合使用会使我感到恐惧。小心!测试!测试!如果您有患者,他们将感谢您。

,

问题在于将替换结果强制转换为未签名。

使用后:

REGEXP_SUBSTR(
    LOWER(article.name),"[:digit:]+[:space:]*ml"
) AS volume

代替GE REGEXP_REPLACE并删除未签名的转换(无论使用双括号还是单括号),REGEXP都可以正常工作。