首页 > 解决方案 > 来自 PCRE REGEXP 的 MySQL REGEXP_REPLACE 翻译

问题描述

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


给定以下数据:

  1. 300毫升的东西
  2. 300毫升的东西
  3. 一些特别的东西(300 毫升)
  4. 8-v 不应该匹配的东西

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

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


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

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

...使用手册character_class中定义的 es 。

问题: escharacter_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找到字符串。

标签: mysqlregexregexp-replacemysql-8.0

解决方案


尝试这个:

       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 的 REGEX_SUBSTR()实现不接受MySQL 的可选参数

我不得不说,在医疗保健 IT 部门工作过,将正则表达式与药物剂量结合起来让我感到害怕。当心!测试!测试!如果你有病人,他们会感谢你的。


推荐阅读