Postgres正则表达式分隔多个可选匹配

时间:2018-04-10 16:55:23

标签: regex postgresql

假设需要在PostgreSQL中分隔文本字段。格式为'abcd',其中每个变量可以是以下任意一个:1.4351015,{{ 1}}或20。这是一个带有一些例子的查询,然后是他们的预期结果:

N/A

结果:

WITH example AS(
SELECT '10N/AN/AN/A' AS bw
UNION SELECT '1010N/AN/A'
UNION SELECT '101020N/A'
UNION SELECT '35N/A1.4'
UNION SELECT '1010N/A10'
UNION SELECT '105N/AN/A'
UNION SELECT '1.43N/A20'
)
SELECT
    bw
    ,regexp_replace(
        regexp_replace(
            regexp_replace(
                regexp_replace(
                    regexp_replace(
                        regexp_replace(
                            regexp_replace(bw, '(1\.4)', E'\\&|', 'g')
                        , '(3)', E'\\&|', 'g')
                    , '(5)', E'\\&|', 'g')
                , '(10)', E'\\&|', 'g')
            , '(15)', E'\\&|', 'g')
        , '(20)', E'\\&|', 'g')
    , '(N/A)', E'\\&|', 'g')

FROM
    example

我并不担心尾随管道' |'因为我可以处理它。这让我得到了我想要的东西,但我担心我可以更简洁地做到这一点。我尝试将每个捕获组放在一个regexp_replace语句中,同时搜索文档,但我无法得到这些结果。

这可以在一个regexp_replace语句中实现吗?

1 个答案:

答案 0 :(得分:2)

您可以使用capturing group构建(1\.4|3|5|1[50]|20|N/A) alternation operators来分隔备选项并替换为\1|

select regexp_replace('35N/A1.4', '(1\.4|3|5|1[50]|20|N/A)', '\1|','g'); 
-- 35|N/A|1.4|

请参阅online demo

<强>详情

  • ( - 启动捕获组构造
  • 1\.4 - 1.4子字符串(.必须进行转义才能被解析为文字点,否则,它会与任何字符匹配)
  • | - 或
  • 3 - 3字符
  • | - 或
  • 5 - 5字符
  • | - 或
  • 1[50] - 1后跟50[...]称为括号表达式,您可以在其中指定字符,字符范围甚至人物类)
  • | - 或
  • 20 - 20子字符串
  • | - 或
  • N/A - N/A子字符串
  • ) - 捕获组的结束。

替换模式中的\1numbered replacement backreference(也称为(组)占位符),它引用捕获到组1中的值。