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

时间:2018-07-25 23:14:18

标签: regex postgresql postgresql-9.5

我有下表:

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文档中找不到所需的内容。我期望获得第一个数字部分,然后是一个空格,然后是MG,GM或MCG。我认为它会与MG组合在一起,然后是GM或MCG。

1 个答案:

答案 0 :(得分:1)

主要思想是,您需要对分组替代项,这些替代项应在字符串的一个位置和相同位置匹配。另外,我建议使用单词边界将字符串作为整个单词进行匹配。

另外,请注意,substring仅返回被捕获组捕获的那部分匹配,如果有的话:

  

如果模式包含任何括号,则返回与第一个带括号的子表达式(左括号在前的那个)匹配的文本部分。

因此,您可能使用的分组构造是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)-MGGMMCG(您可以将其写为(?:MC?G|GM)来提高效率)
  • \M-字尾。

enter image description here