我有一个字段message
,其字符串为<pika> [SOME_TEXT_WITH|ACTION] And other stuff...
。
我想捕捉括号内的内容。我使用以下形式:
SELECT
substring(message FROM '%> \[#"[A-Z_\|]+#"\] %' FOR '#') AS my_info
FROM my_table;
但它始终失败并出现相同的错误消息:«无效的正则表达式:括号()不平衡»。我做错了什么?
答案 0 :(得分:2)
就个人而言,我使用的是perl兼容的现代正则表达式而不是可怕的POSIX-esque regexp:
regress=> SELECT (regexp_matches('<pika> [SOME_TEXT_WITH|ACTION] And other stuff...', '\[(.*?)\]'))[1];
regexp_matches
-----------------------
SOME_TEXT_WITH|ACTION
(1 row)
如果要使用POSIX语法,则必须始终使用相同的转义,而不是某些地方使用\
而其他地方则#
。例如:
regress=> SELECT substring(
'<pika> [SOME_TEXT_WITH|ACTION] And other stuff...'
FROM '%#"#[%#]#"%' FOR '#'
);
substring
-------------------------
[SOME_TEXT_WITH|ACTION]
(1 row)
文档并未明确表示捕获运算符实际上是<ESCAPECHAR>"
,而不是#"
。这同样有效,使用常规反斜杠转义:
regress=> SELECT substring(
'<pika> [SOME_TEXT_WITH|ACTION] And other stuff...'
FROM '%\"\[%\]\"%' FOR '\'
);
substring
-------------------------
[SOME_TEXT_WITH|ACTION]
(1 row)
奇怪错误的原因是PostgreSQL将POSIX SIMILAR TO
样式表达式转换为封面下的真实正则表达式。你的混合逃脱正则表达式:
'%> \[#"[A-Z_\|]+#"\] %' FOR '#'
正在转变为:
'.*> \\[([A-Z_\\|]+)\\] .*'
导致:
regress=> SELECT (regexp_matches('<pika> [SOME_TEXT_WITH|ACTION] And other stuff...', '.*> \\[([A-Z_\\|]+)\\] .*'))[1];
ERROR: invalid regular expression: parentheses () not balanced
答案 1 :(得分:1)
我认为以下是您想要的:
SELECT substring(cast(message as varchar(1000)) FROM '.*\[([A-Z_\|]*)\].*'
)
FROM my_table;