仅匹配字符串末尾的匹配项

时间:2017-04-24 18:19:51

标签: regex postgresql

我想保护下表中的email字段:

CREATE TABLE users (
  email VARCHAR(255) NULL CHECK (email ~* '\A[^@]+@[^@]+\Z')
);

我想要做的是允许字符串,如:

  

鲍勃@示例

但我想避免使用以下字符串:

  

鲍勃@例如\ nfuu

我听说\Z约束允许在另一行之后的任何字符(\n)。

根据正则表达式中的最佳做法,\z优于\Z,因为它只允许一行,但it seems to be not supported by PostgreSQL$并不是更好。

我是真的吗?

编辑:

我测试了这个:

CREATE TABLE users (
  email VARCHAR(255) NULL CHECK (email ~* '\A[^@\n]+@[^@\n]+\Z')
);

CREATE UNIQUE INDEX users__lower_case__email ON users(lower(email));

--

INSERT INTO users (email) VALUES ('\nfoo\n@\nbar\n');

显然约束不起作用:表格中添加了错误的电子邮件。

2 个答案:

答案 0 :(得分:1)

请注意,否定字符类匹配任何字符在集合中定义的字符。因此,[^@]匹配任何字符,但@包括换行符号。要排除换行符,只需将其添加到类中即可。

使用

email ~* '\A[^@\n]+@[^@\n]+\Z'

只有\Z matches only at the end of the string这个正则表达式无法在输入中允许换行。

答案 1 :(得分:0)

我强烈建议您查看我的帖子,了解在PostgreSQL中存储电子邮件地址的正确方法。

以下是一些示例代码,

CREATE EXTENSION citext;
CREATE DOMAIN email AS citext
  CHECK ( value ~ '^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$' );

SELECT 'asdf@foobar.com'::email;

对于你的桌子,

CREATE TABLE users (
  user_email  email
);