复杂的PG正则表达式查询



我有以下工作函数,用于检查约束(我只发布相关的SQL部分(:

-- a comma should always be followed by a space
-- a period should always be followed by a space, except if it is the last character of the string OR the string contains 'caporal'
-- a question mark should always be followed by a space, except if it is the last character of the string
-- must not contain 2 or more spaces in a row
-- must not contain ((
-- must not contain ))
-- any open parenthesis should be closed: number of '(' should equal to number of ')'
SELECT
($1 !~ ',(?!s)|s{2}|[?](?!s(?!$)|$)|[()]{2,}') AND
((array_length(string_to_array($1, '('), 1) - 1) = (array_length(string_to_array($1, ')'), 1) - 1)) AND
($1 ~ 'caporal' OR $1 !~ '[.](?!s(?!$)|$)')

加班我意识到我需要允许一段时间没有以下空间的情况:

  • .fr
  • .com
  • .net
  • .co.uk

此外,我意识到我需要允许用逗号/句点作为分隔符来写浮点数。以下情况应有效:

  • 2,5cm
  • 10.4l

我尝试了多种方法,但似乎我只是在打破现有规则,而不是添加";例外情况";他们。

我的后一次尝试是:

SELECT
($1 !~ '[[a-zA-Z]àâçéèêëîïôûùüÿæœ],(?!s)|s{2}|[?](?!s(?!$)|$)|[()]{2,}') AND
((array_length(string_to_array($1, '('), 1) - 1) = (array_length(string_to_array($1, ')'), 1) - 1)) AND
($1 ~ 'caporal' OR $1 !~ '[[a-zA-Z]àâçéèêëîïôûùüÿæœ][.](?!s(?!$)|(?!fr)|(?!com)|$)')

但这显然不是我想要的。提前感谢您的提示和建议!

您应该将第一个正则表达式更改为

,(?!d(?<=d,d)|s)|s{2}|?(?!s(?!$)|$)|[()]{2,}

最后一个是

.(?!d(?<=d.d)|(?:fr|com|co.uk|(?<=yco.)uk|net)y|s(?!$)|$)

这些变化是对负lookahead的添加,如果它们的模式立即匹配到当前位置的右侧,则匹配失败。

在第一种情况下,,(?!d(?<=d,d)|s)用于匹配任何后面没有空格的逗号或任何小数位数(因为它前面必须有数字和逗号(。

在第二个正则表达式中,添加了类似的限制,请参阅d(?<=d.d),它使.与一个不是浮点数中第一个小数点的点匹配,并使用句点作为小数分隔符,添加(?:fr|com|co.uk|(?<=yco.)uk|net)y部分以避免与后面跟着frcomco.uk.匹配,co.uk中的第二个周期((?<=yco.)uk查找确保uk之前没有co.的逗号仍然匹配(或net中的整个单词(参见y,单词边界(。

最新更新