** 认识正则表达式 **
如果原来没有使用过正则表达式,那么可能对这个术语和概念会不太熟悉。不过,它们并不是您想象的那么新奇。
请回想一下在硬盘上是如何查找文件的。您肯定会使用 ? 和 * 字符来帮助查找您正寻找的文件。 ? 字符匹配文件名中的单个字符,而 * 则匹配一个或多个字符。一个如 'data?.dat' 的模式可以找到下述文件:
data1.dat
data2.dat
datax.dat
dataN.dat
如果使用 * 字符代替 ? 字符,则将扩大找到的文件数量。 'data*.dat' 可以匹配下述所有文件名:
data.dat
data1.dat
data2.dat
data12.dat
datax.dat
dataXYZ.dat
尽管这种搜索文件的方法肯定很有用,但也十分有限。 ? 和 * 通配符的有限能力可以使你对正则表达式能做什么有一个概念,不过正则表达式的功能更强大,也更灵活。
** 正则表达式的早期起源 ** ** **
正则表达式的 “ 祖先 ” 可以一直上溯至对人类神经系统如何工作的早期研究。 Warren McCulloch 和 Walter Pitts 这两位神经生理学家研究出一种数学方式来描述这些神经网络。
1956 年 , 一位叫 Stephen Kleene 的美国数学家在 McCulloch 和 Pitts 早期工作的基础上,发表了一篇标题为 “ 神经网事件的表示法 ” 的论文,引入了正则表达式的概念。正则表达式就是用来描述他称为 “ 正则集的代数 ” 的表达式,因此采用 “ 正则表达式 ” 这个术语。
随后,发现可以将这一工作应用于使用 Ken Thompson 的计算搜索算法的一些早期研究, Ken Thompson 是 Unix 的主要发明人。正则表达式的第一个实用应用程序就是 Unix 中的 _ qed _ 编辑器。
如他们所说,剩下的就是众所周知的历史了。从那时起直至现在正则表达式都是基于文本的编辑器和搜索工具中的一个重要部分。
** 使用正则表达式 ** ** **
在典型的搜索和替换操作中,必须提供要查找的确切文字。这种技术对于静态文本中的简单搜索和替换任务可能足够了,但是由于它缺乏灵活性,因此在搜索动态文本时就有困难了,甚至是不可能的。
使用正则表达式,就可以:
ü 测试字符串的某个模式。例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式。这称为数据有效性验证。
ü 替换文本。可以在文档中使用一个正则表达式来标识特定文字,然后可以全部将其删除,或者替换为别的文字。
ü 根据模式匹配从字符串中提取一个子字符串。可以用来在文本或输入字段中查找特定文字。
例如,如果需要搜索整个 web 站点来删除某些过时的材料并替换某些 HTML 格式化标记,则可以使用正则表达式对每个文件进行测试,看在该文件中是否存在所要查找的材料或 HTML 格式化标记。用这个方法,就可以将受影响的文件范围缩小到包含要删除或更改的材料的那些文件。然后可以使用正则表达式来删除过时的材料,最后,可以再次使用正则表达式来查找并替换那些需要替换的标记。
** 正则表达式语法 ** ** **
一个正则表达式就是由普通字符(例如字符 a 到 z )以及特殊字符(称为 元字符 )组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
这里有一些可能会遇到的正则表达式示例:
** JScript **
|
** VBScript **
|
** 匹配 ** ** **
---|---|---
/^\[ \t]*$/
|
"^\[ \t]*$"
|
匹配一个空白行。
/\d{2}-\d{5}/
|
"\d{2}-\d{5}"
|
验证一个 ID 号码是否由一个 2 位数字,一个连字符以及一个 5 位数字组成。
/<(.)>.</\1>/
|
"<(.)>.</\1>"
|
匹配一个 HTML 标记。
下表是元字符及其在正则表达式上下文中的行为的一个完整列表:
** 字符 ** ** **
|
** 描述 ** ** **
---|---
\
|
将下一个字符标记为一个特殊字符、或一个原义字符、或一个 后向引用、或一个八进制转义符。例如, 'n' 匹配字符 "n" 。 '\n' 匹配一个换行符。序列 '\' 匹配 "" 而 "\(" 则匹配 "(" 。
^
|
匹配输入字符串的开始位置。如果设置了 ** RegExp ** 对象的 ** Multiline ** 属性, ^ 也匹配 '\n' 或 '\r' 之后的位置。
$
|
匹配输入字符串的结束位置。如果设置了 ** RegExp ** 对象的 ** Multiline ** 属性, $ 也匹配 '\n' 或 '\r' 之前的位置。
|
匹配前面的子表达式零次或多次。例如, zo* 能匹配 "z" 以及 "zoo" 。 * 等价于 {0,} 。
+
|
匹配前面的子表达式一次或多次。例如, 'zo+' 能匹配 "zo" 以及 "zoo" ,但不能匹配 "z" 。 + 等价于 {1,} 。
?
|
匹配前面的子表达式零次或一次。例如, "do(es)?" 可以匹配 "do" 或 "does" 中的 "do" 。 ? 等价于 {0,1} 。
{ n }
|
_ n _ 是一个非负整数。匹配确定的 _ n _ 次。例如, 'o{2}' 不能匹配 "Bob" 中的 'o' ,但是能匹配 "food" 中的两个 o 。
{ n ,}
|
_ n _ 是一个非负整数。至少匹配 _ n _ 次。例如, 'o{2,}' 不能匹配 "Bob" 中的 'o' ,但能匹配 "foooood" 中的所有 o 。 'o{1,}' 等价于 'o+' 。 'o{0,}' 则等价于 'o*' 。
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt