我有以下工作函数,用于检查约束(我只发布相关的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
部分以避免与后面跟着fr
、com
、co.uk
的.
匹配,co.uk
中的第二个周期((?<=yco.)uk
查找确保uk
之前没有co.
的逗号仍然匹配(或net
中的整个单词(参见y
,单词边界(。