如何在 PostgreSQL 中提取数字后跟特定字符串?

How do I extract a number followed by a specific string in PostgreSQL?

我有以下 table:

CREATE TABLE test_regex (
    drug TEXT
);

INSERT INTO test_regex
VALUES
    ('DRUGA 200 MG'),
    ('DRUGB 150 MCG'),
    ('DRUGC 1.5 GM BOX'),
    ('DRUGD 27.2 MG/5 ML VIAL')
;

我要提取以下内容:

200 MG
150 MCG
1.5 GM
27.2 MG

到目前为止我尝试过的:

SELECT
    substring(drug, '[0-9]*\.?[0-9]* MG|GM|MCG')
FROM
    test_regex
;

这导致:

 200 MG
 MCG
 GM
 27.2 MG

我也试过:

SELECT
    substring(drug, '[0-9]*\.?[0-9]* (MG|GM|MCG)')
FROM
    test_regex
;

结果如下:

 MG
 MCG
 GM
 MG

我认为问题在于尾随 (MG|GM|MCG) 组的处理方式,但我无法在 PostgreSQL 文档中找到我要找的内容。我期待得到第一个数字部分,然后是 space,然后是 MG、GM 或 MCG。我认为它被分组为 MG 的数字表达式,然后是 GM 或 MCG。

主要思想是您需要分组 应在字符串中的同一位置匹配的备选方案。另外,我建议使用单词边界来匹配整个单词的字符串。

此外,请注意 substring returns 只有匹配的那部分 被捕获组捕获 如果有的话:

if the pattern contains any parentheses, the portion of the text that matched the first parenthesized subexpression (the one whose left parenthesis comes first) is returned.

因此,您可以使用的分组结构是 non-capturing group(?:...|...)

您可以使用

substring(drug, '\m[0-9]*\.?[0-9]+\s*(?:MG|GM|MCG)\M')

online demo

图案详情

  • \m - 单词的开头
  • [0-9]* - 零个或多个数字
  • \.? - 一个可选的 .
  • [0-9]+ - 1+ 位数
  • \s* - 0+ 个空格
  • (?:MG|GM|MCG) - MG,或GMMCG(您可以将其写为(?:MC?G|GM)以提高效率)
  • \M - 单词结束。