正则表达式(一)
一、 简介
正则表达式这个名词,相信很多人都听说过,这个名词最早起源于 1956 年 , 一位叫 Stephen Kleene 的美国数学家在 McCulloch 和 Pitts 早期工作的基础上,发表了一篇标题为 “ 神经网事件的表示法 ” 的论文,引入了正则表达式的概念。正则表达式就是用来描述他称为 “ 正则集的代数 ” 的表达式,因此采用 “ 正则表达式 ” 这个术语。
随后,发现可以将这一工作应用于使用 Ken Thompson 的计算搜索算法的一些早期研究, Ken Thompson 是 Unix 的主要发明人。正则表达式的第一个实用应用程序就是 Unix 中的 qed 编辑器。
Q: 正则表达式,能够为我们做什么呢?
A: 基于文本的编辑器和搜索工具中的一个重要部分。正则表达式可以让用户通过使用一系列的特殊字符构建匹配模式,然后把匹配模式与数据文件、程序输入以及 WEB 页面的表单输入等目标对象进行比较,根据比较对象中是否包含匹配模式,执行相应的程序。
下面我们就一步一步的结合它的语法,来介绍正则表达式的使用。
二、 初次接触正则表达式
我们先来了解正则表达式的一些基本概念。正则表达式作为一种表示语言,其定义了自己的一套描述方式,来描述各种各样的字符类。下面摘取 msdn 中的一段定义。( ms-help://MS.VSCC/MS.MSDNVS.2052/cpgenref/html/cpconcharacterclasses.htm )
字符转义表
** 字符类 **
|
** 含义 **
---|---
.
|
与除 \n 以外的任何字符匹配。如果通过 Singleline 选项(请参阅 _ 正则表达式选项 _ )进行了修改,则句点字符与任何字符匹配。
[aeiou]
|
与指定字符集中包含的任何单个字符匹配。
[^aeiou]
|
与不在指定字符集中的任何单个字符匹配。
[0-9a-fA-F]
|
使用连字号 (–) 允许指定连续字符范围。
\p{name}
|
与 name 指定的命名字符类中的任何字符匹配。支持的名称为 Unicode 组和块范围。例如 Ll£¬Nd£¬Z£¬IsGreek£¬IsBoxDrawing。
\P{name}
|
与在 {name} 中指定的组和块范围中未包含的文本匹配。
\w
|
与任何单词字符匹配。等效于 Unicode 字符类别
[\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}]。如果通过 _ ECMAScript 选项 _ 指定了符合 ECMAScript 的行为,则 \w 等同于 [a-zA-Z_0-9]。
\W
|
与任何非单词字符匹配。等效于 Unicode 类别 [^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}]。如果通过 _ ECMAScript 选项 _ 指定了符合 ECMAScript 的行为,则 \W 等同于 [^a-zA-Z_0-9]。
\s
|
与任何空白字符匹配。等效于 Unicode 字符类别 [\f\n\r\t\v\x85\p{Z}]。如果通过 _ ECMAScript 选项 _ 指定了符合 ECMAScript 的行为,则 \s 等同于 [ \f\n\r\t\v]。
\S
|
与任何非空白字符匹配。等效于 Unicode 字符类别 [^\f\n\r\t\v\x85\p{Z}]。如果通过 _ ECMAScript 选项 _ 指定了符合 ECMAScript 的行为,则 \S 等同于 [^ \f\n\r\t\v]。
\d
|
与任何十进制数字匹配。与 Unicode 的 \p{Nd} 和非 Unicode 的 [0-9] 以及 ECMAScript 行为一样。
\D
|
与任何非数字匹配。与 Unicode 的 \P{Nd} 和非 Unicode 的 [^0-9] 以及 ECMAScript 行为一样。
上表列举了,正则表达式中最最基本的语法定义,了解这些,我们已经可以定义一些简单的规则了,例如:
1. 匹配所有的字符
当然是什么都不用写( @_@)
2. 匹配所有的英文字符
a) \w
b) [a-zA-Z_0-9]
3. 匹配十进制数字
a) \d
b) [0-9]
看上面的例子,是不是觉得很简单呢,不过,到目前为止,这样写出来的规则,还有一个很大的缺陷,就是没有声明匹配字符的个数?
Q: 我希望要匹配的字符为 5 个英文字母
A: ???
光了解上面的知识是,无法解决这个的 L 。那正则表达式中是如何解决这个问题的呢,我们来看下面这个表:
( ms-help://MS.VSCC/MS.MSDNVS.2052/cpgenref/html/cpconquantifiers.htm)
限定符表
** 限定符 **
|
** 说明 **
---|---
|
指定零个或更多个匹配;例如 \w* 或 (abc)*。与 {0,} 相同。
+
|
指定一个或多个匹配;例如 \w+ 或 (abc)+。与 {1,} 相同。
?
|
指定零个或一个匹配;例如 \w? 或 (abc)?。与 {0,1} 相同。
{n}
|
指定恰好 n 个匹配;例如 (pizza){2}。
{n,}
|
指定至少 n 个匹配;例如 (abc){2,}。
{n,m}
|
指定至少 n 个但不多于 m 个匹配。
*?
|
指定尽可能少地使用重复的第一个匹配 (lazy *)。
+?
|
指定尽可能少地使用重复但至少使用一次 (lazy +)。
??
|
指定使用零次重复(如有可能)或一次重复 (lazy ?)。
{n}?
|
等效于 {n} (lazy {n})。
{n,}?
|
指定尽可能少地使用重复,但至少使用 n 次 (lazy {n,})。
{n,m}?
|
指定介于 n 次和 m 次之间、尽可能少地使用重复 (lazy {n,m})。
上表中列出了,正则表达式的限定方式,配合这些字符的使用,我们就可以很方便的编写更为强劲的正则表达式了。
例如:
1. 匹配 零个或多个 所有的字符
2. 匹配 一个或多个 所有字符
+
3. 匹配 零个或多个 所有的英文字符
\w*
4. 匹配 一个或多个 所有的英文字符
[a-zA-Z0-9]+
5. 匹配 3个 十进制数字
\d{3}
6. 匹配 最少 3个 十进制数字
\d{3,}
7. 匹配 3个到6个 十进制数字
\d{3,6}
现在我们可以解答上面问题了:
Q: 我希望要匹配的字符为 5 个英文字母
A: \w{5}
很高兴,我们已解决了上面的问题,不过,新的问题总是在不断的出现。我如何限制匹