校验合法邮箱:正则里的点要转义
LeetCode 1517 · REGEXP 正则、字符串校验
面试怎么回答
mail REGEXP '^[A-Za-z][A-Za-z0-9_.-]*@leetcode[.]com$':开头一个字母,后面零个或多个合法字符,域名里的点放进方括号表示字面量。三个坑:点要转义、单字母前缀要允许、REGEXP 默认不区分大小写。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
题意
用户表记录邮箱。合法邮箱是:前缀以字母开头,后面可以是字母、数字、下划线、点或短横线;域名必须是 @leetcode.com。找出所有邮箱合法的用户。
表结构
- Users:user_id(主键)、name、mail
思路
用正则从头到尾完整匹配:^ 开头一个字母,然后零个或多个允许的字符,最后是 @leetcode\.com$。正则里的点代表任意字符,必须转义(或者放进 [.]),否则 leetcodeXcom 也会通过。原文第一种写法域名里的点没有转义。
参考解法
写法 1
SELECT *
FROM Users
WHERE mail REGEXP '^[a-zA-Z]+[\\w_\\.\\-]*@leetcode.com$'
ORDER BY user_id;
写法 2
select * from Users
where mail regexp '^[a-zA-Z]+[a-zA-Z0-9_\\./\\-]{0,}@leetcode.com$'
order by user_id
另一种写法:点用 [.] 表示,前缀后续字符允许 0 个
SELECT *
FROM Users
WHERE mail REGEXP '^[A-Za-z][A-Za-z0-9_.-]*@leetcode[.]com$'
易错点
- 域名中的点不转义,会匹配任意字符。
- 前缀只有一个字母也是合法的,所以后续字符要用
*而不是+。 - MySQL 的 REGEXP 默认不区分大小写,要严格区分域名大小写时需要 BINARY 或对应的排序规则。