将Oracle函数regexp_instr转换为Posgresql

时间:2018-12-31 15:52:55

标签: oracle postgresql

将Oracle 11g模式转换为Postgresql 11时遇到了一个Oracle函数,如下所示:

ADD CONSTRAINT valid_session_time_zone CHECK (regexp_instr(trim(both session_time_zone),'(\+|\-|\s)?(0?[0-9]|1[01234])(:[0-5]\d)')=1);

所以我将其翻译为PostgreSQL 11域

CREATE DOMAIN chk_time_zone AS VARCHAR CHECK ( VALUE ~* '(\+|\-|\s)?(0?[0-9]|1[01234])(:[0-5]\d)');

但是如何在域表达式中预先修剪字符串的两侧?

2 个答案:

答案 0 :(得分:1)

也许这只是我的视力不好,但在我看来原始代码有问题。原始的正则表达式要求匹配的字符串以+-或空白之一开头,但是TRIM调用将删除所有前导空白。因此,如果要匹配的字符串以其后没有+-的空格开头,则TRIM调用将删除该空格,因此该模式将不匹配。我的建议是仅忽略存在TRIM调用的事实,因为它似乎是潜在的错误,并以~* '(\+|\-|\s)?(0?[0-9]|1[01234])(:[0-5]\d)'进行匹配。

答案 1 :(得分:0)

您的Oracle检查不会处理输入到表中的数据,它只是检查它的修剪版本是否与模式匹配,因此显然可以插入前导/尾随空格,或者其他地方也可以修剪它们...

因此,我认为您可以要求PGSQL通过在模式中允许它来忽略前导/尾随空格:

CREATE DOMAIN chk_time_zone AS VARCHAR CHECK 
( VALUE ~* '\s*(\+|\-|\s)?(0?[0-9]|1[01234])(:[0-5]\d)\s*');

请注意,输入的正则表达式不包含开头或结尾的任何锚点,因此该模式可能出现在数据中的任何位置以进行匹配。如果输入必须完全匹配模式,则在正则表达式的开头添加^,在$的末尾添加$

例如:'abcdef'匹配'[cd]+'但不匹配'^[cd]+$'