PostgreSQL:.csv 正则表达式 - 测试字符串(数字)中的重复子字符串

PostgreSQL: .csv regex - test for repeating substrings within a string (digits)

简介:

我在 PostgreSQL 中有以下场景,我想在将 .csv 字符串插入 table 之前对它执行一些数据验证(参见 fiddle here) .

我已经设法得到一个正则表达式(在 CHECK 约束中),它不允许字符串中有空格(例如“12 34”)并且也不允许前面的零(“00343 ").

现在,锦上添花的是,如果我可以使用正则表达式来禁止包含重复整数的字符串 - 即,如果序列 \d+ 与同一序列中的另一个 \d+ 匹配字符串。

这是否超出了正则表达式的能力范围?

我的table如下:

CREATE TABLE test
(
  data TEXT NOT NULL,
  
  CONSTRAINT d_csv_only_ck 
    CHECK (data ~ '^([ ]*([1-9]\d*)+[ ]*)(,[ ]*([1-9]\d*)+[ ]*)*$')

);

我可以按如下方式填充它:

INSERT INTO test VALUES 
('992,1005,1007,992,456,456,1008'),  -- want to make this line unnacceptable - repeats!
('44,1005,1110'), 
('13,  44  ,  1005,  10078  '),  -- acceptable - spaces before and after integers   
('11,1203,6666'),
('1,11,99,2222'),
('3435'),             
('  1234    '); -- acceptable

但是:

INSERT INTO test VALUES ('23432, 3433   ,00343, 567'); -- leading 0 - unnacceptable

失败了(它应该如此),也失败了(再次,它应该如此)

INSERT INTO test VALUES ('12  34');  -- spaces within numbers - unnacceptable

问题:

但是,如果您注意到第一个字符串,它会重复 992456

我希望能够匹配这些。

所有这些规则不必在同一个正则表达式中 - 我可以使用第二个 CHECK 约束。

我想知道我所问的是否可以使用正则表达式?

我确实找到了这个 which appears to go some (all?) of the way to solving my issue, but I'm afraid it's beyond my skillset to get it to work - I've included a small test at the bottom of the fiddle

如果您需要任何进一步的信息,请告诉我。

p.s。顺便说一句,我对正则表达式不是很有经验,我欢迎任何关于我上面的基本的输入。

自从 PostegreSQL 正则表达式 does not support backreferences 以来,您不能应用此限制,因为您需要一个带有反向引用的否定前瞻。

看看这个 PCRE 正则表达式:

^(?!.*\b(\d+)\b.*\b\b) *[1-9]\d* *(?:, *[1-9]\d* *)*$

参见 this regex demo详情:

  • ^ - 字符串开头
  • (?!.*\b(\d+)\b.*\b\b) - 字符串中的任何位置都不允许出现与整个单词相同的两个数字
  • * - 零个或多个空格
  • [1-9]\d* - 一个非零数字,然后是任何零个或多个数字
  • * - 零个或多个空格
  • (?:, *[1-9]\d* *)* - 零次或多次出现
    • , * - 逗号和零个或多个空格
    • [1-9]\d* - 一个非零数字,然后是任何零个或多个数字
    • * - 零个或多个空格
  • $ - 字符串结尾。

即使您在 PostgreSQL 代码中将 \b 替换为 \y(PostgreSQL 正则表达式单词边界),由于答案顶部提到的缺点,它也不会工作。