正则表达式介绍
原文:An Introduction to Regular Expressions
作者:Tom Elliott
译者:kmyhy
正则表达式(也叫“正则式”)是一个用于表示某种模式的字符串或者字符序列。可以把它看成是搜索字符串——但是功能要强大得多!
在文本编辑器或字处理软件中能够进行纯文本搜索。正则表达式也能进行这种简单的搜索,更胜一筹的是,它还允许你搜索模式,比如 2 位数字 + 1 位字母,或者 3 个字母 + 1 个连字符号。
这种模式允许你实现一些有用的功能比如校验字段(电话号码、email 地址),检查用户输入,进行高级文本操作等等。
用底部的 download materials 按钮可以下载一个 Regular Expression Cheat Sheet pdf 文件和一个练习时使用到的 Swift playground 的文件。你可以将 Cheat Sheet 打印出来作为开发时的参考书。在 Swift playground 文件中包含了几个示例,可以用它来测试各种正则表达式。所有的正则表达式例子,无论是本教程中的还是后面一个教程的,在这个 playground 中都有现成的例子,你可以参考它们。
基本概念
如果你刚接触正则表达式,不知道它是干什么的,那么你可以看这个解释:正则表达式是一种搜索指定文本是否匹配某个模板的方法。关于正则表达式有大量精彩的书籍和教程——请参考本文最后的列表。
正则表达式的 Playground 脚本
在本教程中,我们会编写许多正则表达式。如果在编写它们的过程中能够直观地看到结果,那么用 Swift 写一个 Playground 脚本是一个绝佳的好办法!
在下载的 playground 文件的开头包含许多函数,用于将一段文本中的正则表达式搜索结果高亮出来,在 playground 的结果模板中显示匹配列表或分组列表,以及文本。现在无须关心这些方法是怎么实现的,你会在下一篇教程中学习它们。现在,跳到 Basic Examples and Cheat Sheet 部分,开始学习那些例子。
在 playground 的结果栏中,你会看到每个例子的匹配列表。对于高亮的例子,你可以将鼠标放在结果上面,点击眼睛或空心圆图标,就会高亮显示出匹配的文本。
后面我们会学习如何来创建 NSRegularExpression,现在我们来使用以下这个 playground,感受一下各种正则表达式是如何工作的,并尝试编写自己的模板。
示例
让我们从几个简单的例子开始。
例如匹配单词 jump 的例子:
jump
这是最简单的正则表达式。你可以在 iOS 中通过 API 搜索文本字符串中是否匹配这个表达式——如果找到匹配,你就可以拿到它的位置或者替换成其它文本。
还有稍微复杂一点的例子,同时匹配单词 jump 和 jumps:
jump(s)?
这个例子中使用了特殊字符。括号可以创建分组,问号表示匹配前面的元素(即分组)0 次或 1 次。
真正复杂的例子来了。匹配一堆HTML开始/结束标签以及两者之间的内容:
<([a-z][a-z0-9])\b[^>]>(.*?)</\1>
哇,好复杂的样子。别担心,在接下来的教程中,你会学习这个表达式中所有的特殊字符,你最终会明白它的含义的!:]
如果你想深究上面的表达式,请参考下面的这个解释。
注:在现实生活中,你不应该用正则表达式来解析 HTML。而应该使用标准的 XML 解析器。
整体概念
在继续学习之前,首先需要理解几个正则表达式的概念。
原义字符是最简单的正则表达式。它们类似于字处理器或文本编辑器中的查找功能。例如,查找单个字符的表达式 t 将查找所有出现字母 t 的地方,而表达式 jump 则会查找所有出现 jump 的地方。非常简单吧!
和编程语言一样,在正则表达式语法中也存在转义字符,比如:
[
( 和 )
\
*
+
?
{ 和 }
^
$
.
| (管道符)
/
这些字符表示高级模板匹配。如果你想搜索这些字符,你必须用反斜杆进行转义。例如,要搜索圆点 . 符号,要使用 . 而不是 .。
不同的环境,比如 Python、Perl、Java、C#、Ruby 等,它们对正则表达式的实现都会有细微差别。Swift 也不例外!
无论 O-C 还是 swift 都需要对常量字符串中的特殊字符进行转义(比如,加一个反斜杠 \)。而反斜杠自身也是一个特殊字符。因为正则表达式模板也是字符串,因此当使用字符串和 NSRegularExpression 时,你必须对字符串中的反斜杠进行转义。
因此在你的 Swift(或 O-C)代码中,标准的正则表达式 . 应该写成 \.。
总结一下:
- “\.” 表示字符串:.
- 正则表达式 . 匹配 . 字符。
**捕获(圆括号)**用于将模板进行分组。例如,3(pm|am)会匹配 “3 pm” 和 “3 am”。管道符(|)相当于或(OR) 。在正则表达式中可以有任意多的管道符。例如,(Tom|Dick|Harry) 可以匹配三个名字中的任意一个。
如果你需要指定某个字符串是可选的,可以使用圆括号进行分组。比如你想搜索字符串中的 “November”,但用户有可能会对这个月份使用简写 “Nov”,那么你可以使用模板 Nov(ember)?。即在圆括号后面加一个 ?号,表示圆括号中的内容是可选的。
我们将圆括号称作“捕获”是因为它会将匹配的内容捕获给你,让你正则式的其它地方引用它。
例如,假设有一个字符串 “Say hi to Harry”。如果that guy $1
创建一个正则表达式去替换用 (Tom|Dick|Harry)搜索到的结果,则会将文字变成 “Say hi to that guy Harry”。$1
表示引用上一次处理中的第一个捕获组。
捕获和非捕获组稍微有点难。你会在后续教程中看到捕获和非捕获组的内容。
Character 类用于表示一个单个字符,它可能是一系列字符中的一个。Character 类一般出现在一对方括号之间。
例如,t[aeiou] 会匹配 “ta”, “te”, “ti”, “to”, 或 “tu”。在方括号中可以有任意多字符,但只会匹配其中一个。[aeiou] 包含 5 个字符,但要么是 a,要么是 e,要么是 i,要么是 o,或者是 u。
你可以在 Character 类中指定字符可能存在的范围。例如,如果要匹配一个从 100 到 109 之间的数字,你可以用 10[0-9]。这等同于 10[0123456789],但通过范围的指定,你的正则表达式显得更加清晰、易读。
Character 类不仅仅限于数字——也可以用于表示字母。例如,[a-f] 会匹配 a、b、c、d、e、f。
Character 类通常包含了你想匹配的字符,但如果你想让表达式不匹配某个字符怎么办?你可以定义一个否定的 Character 类,即使用 ^ 进行打头。例如,t[^o]表示匹配字母 t 和一个不是 o 的字符,即排除了单词 to。
NSRegularExpression 速查表
正则表达式很多时候语法都很简单,但也有一些极其复杂的例子!哪怕是最厉害的正则表达式专家,也需要有一个速查表,已应对那些棘手的问题。
在下载内容中包括了一个 pdf, 它是 ranwenderlich.com 官方提供的正则表达式速查表。
此外,这里罗列了一下速查表中的一些简单写法和对应解释:
- . 匹配任意字符。p.p 匹配 pop、pup、pmp、[email protected] 等。
- \w 匹配任意“单词类”的字符,包括数字、字母、下划线,但不包括标点符号或其他符号。hello\w 匹配 hello_、hello9、helloo,但不匹配 hello!
- \d 匹配一位数字,也就是 [0-9]。\d\d?:\d\d 匹配时间字符串,比如 9:00 和 12:45。
- \b 匹配单词分隔符,比如空格和标点符号。to\b 匹配 “to the moon” 中的 “to” 和 “to!”,但不匹配 “tommorrow”。\b 可用于整词匹配。
- \s 匹配空白字符,比如空格、tab、换行符。hello\s 匹配字符串 “Well, hello there!” 中的 “hello”。
- ^ 匹配一行的开始。注意这个 ^ 和方括号中的 ^ 是不一样的!例如,^Hello 匹配 “Hello there”,但不匹配 “He said Hello”。
-
$
匹配行末。例如,end$ 匹配 “It was the end” 但不匹配 “the end was near”。 -
*
匹配前一个元素 0 次或多次。12*3 匹配 13、123、1223、122223、1222222223. -
+
匹配前一个元素 1 次或多次。12+3 匹配 123、1223、122223、1222222223,但不匹配 13。 - 花括号 {} 中包含一个最小匹配次数和一个最大匹配次数。例如,10{1,2}1 匹配 101、1001,但不匹配 10001,因为最小次数是 1,最大次数是 2。He[Ll]{2,}o 会匹配 “HeLLo” 和 “HellLLLllo” 以及 “hello” 中有人一个 L 的变体,因为最小数是 2,最大数缺失——这表示不限次数。
作为初学,这就足够了。
这时应该自动动手实验下这些例子,它们全都在上面所提的 playground 中包含了。
接下来去哪?
关于正则表达式,下面罗列了一些有用的链接:
- www.regular-expressions.info 是 Jan Goyvaerts 的主页。他也出版了基本关于正则表达式的全面
- NSRegularExpression 类参考是 NSRegularExpression API 的重要参考。
- 要快速测试正则表达式模板,可以使用 regexpal.com 。
一定要下载“正则表达式速查 pdf”和练习用的 playground,下载按钮在最后。
请到我们的 NSRegularExpression 教程 中看看如何在 Swift 中使用正则表达式!:]