正则表达式:没看起来那么可怕
正则表达式以难读著称,但它们不必如此。从基础语法到实用模式,一步步学习如何用正则匹配邮箱、验证手机号和提取数据。
你需要在文档中找到所有邮箱地址。或验证电话号码。或从混乱的文本中提取日期。
有人说"用正则"。你搜索语法,找到像^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$这样的东西,立刻关掉标签页。
正则表达式看起来令人生畏,因为人们写它们是为了聪明而不是清晰。让我们解决这个问题。
从字面匹配开始
正则找模式。最简单的模式是字面文本。
cat在"The cat sat."中匹配"cat"。没什么花哨的。
http在任何URL中匹配"http"。仍然很直接。
逐渐添加通配符
.匹配任何单个字符。c.t匹配"cat"、"cot"、"cut"。
*表示"前面的东西零次或多次"。ca*t匹配"ct"、"cat"、"caat"、"caaaaaat"。
+表示"一次或多次"。ca+t匹配"cat"和"caat"但不匹配"ct"。
?表示"零次或一次"。colou?r匹配"color"和"colour"。
字符类是你的朋友
[aeiou]匹配任何元音。[0-9]匹配任何数字。[A-Za-z]匹配任何字母。
\d是[0-9]的简写。\w匹配单词字符(字母、数字、下划线)。\s匹配空白。
这些构建块处理大多数现实世界的模式。
锚点控制位置
^表示"行首"。$表示"行尾"。
^Hello匹配"Hello world"但不匹配"Say Hello"。
world$匹配"Hello world"但不匹配"world peace"。
组捕获部分
括号分组东西。它们也为以后使用而捕获。
(\d{3})-(\d{4})匹配"555-1234"并分别捕获"555"和"1234"。
这就是你从模式匹配中提取特定数据的方式。
真实示例,解释过的
邮箱(简化版):
[\w.-]+@[\w.-]+\.\w+
翻译:单词字符/点/连字符,然后@,然后更多相同的,然后一个点,然后单词字符。
电话号码:
\d{3}[-.\s]?\d{3}[-.\s]?\d{4}
翻译:3个数字,可选分隔符,3个数字,可选分隔符,4个数字。匹配"555-123-4567"、"555.123.4567"、"5551234567"。
日期(MM/DD/YYYY):
\d{2}/\d{2}/\d{4}
翻译:2个数字,斜杠,2个数字,斜杠,4个数字。
常见错误
忘记转义特殊字符。 .在正则中表示"任何字符"。要匹配字面点,使用\.。
太贪婪。 .*匹配尽可能多。对于HTML标签,<.*>在<b>bold</b>上匹配整个东西,而不只是<b>。用<.*?>进行非贪婪匹配。
过度复杂化。 如果你需要真正验证邮箱,使用库。"正确的"邮箱正则有数百个字符长。
何时不使用正则
解析HTML或JSON。使用适当的解析器。
复杂验证逻辑。代码通常比单个巨大模式更清晰。
当字符串方法有效时。"hello".startsWith("he")比/^he/更清晰。
正则是工具。像任何工具一样,它适合特定工作,不适合其他工作。从简单开始,边建边测试,不要试图聪明。可读的正则比令人印象深刻的正则更好。