`
javasogo
  • 浏览: 1775402 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

简单入门正则表达式 - 第三章 快速入门

 
阅读更多
<style> #content-region { background-image: url(http://p.blog.csdn.net/images/p_blog_csdn_net/rcom10002/EntryImages/20081027/watermark.gif); } #content-region h3 { border: 1px dotted #333333; background-color: #f9f9f9; padding: 10px; font-size: 24px; } #content-region p { font-family: "宋体", "仿宋"; font-size: 16px; line-height: 28px; text-decoration: none; text-indent: 32px; } #content-region .regex-pattern { font-style: oblique; font-family: "Courier New", Courier, monospace; background-color: #FFCCCC; border-top-style: solid; border-right-style: none; border-bottom-style: solid; border-left-style: none; border-top-color: #FF0000; border-bottom-color: #FF0000; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-right-color: #FF0000; border-left-color: #FF0000; padding: 0px 5px 0px 5px; } #content-region .regex-result { font-family: "Courier New", Courier, monospace; background-color: #A4FFE1; border-top-style: solid; border-right-style: none; border-bottom-style: solid; border-left-style: none; border-top-color: #339966; border-bottom-color: #339966; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-right-color: #339966; border-left-color: #339966; padding: 0px 5px 0px 5px; } #content-region blockquote { padding: 10px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; width: auto; } #content-region img { border: 1px dotted #000000; padding: 16px; background-color: #f9f9f9; margin-top: 16px; margin-right: 16px; margin-bottom: 16px; margin-left: 64px; } #content-region code { white-space: pre; } </style>

一、字面值字符

正则表达式的作用就是根据给定的字符样式,来匹配目标字符串。而这种匹配方案中,最简单的就是字面值字符的匹配。

那么,什么叫字面值字符匹配呢?简单的说,就是输入一个样式ABC,就能把目标字符串“智能ABC—输入法,智能ABC输入法,中文输入法,打字,打字ABC,中文ABC”中所有的“ABC”给查找出来。但这个查找过程并不是一次性完成的,正则表达式引擎是先匹配第一个“ABC”,然后再从上一次成功匹配的地方进行第二次匹配。

在正则表达式中,有些字符符号被赋予了特殊的功能,它们通常被称为元字符。如果要对这些字符进行匹配操作,我们就不能像ABC那样直接使用。正则表达式为这类字符提供了一个转义机制,就是在它们之前添加一个“/”作为转义标识。比如我们要匹配“a+b=c”的话,正则表达式的语法就应该是a/+b=c

二、字符集合

字符集合也被称作字符类,它每次只用集合中的一个字符与目标字符串进行匹配。字符集合有两种语法格式:第一种是采用枚举的形式,把每个要匹配的元素放到方括号中[你我他],这样对字符串“是你吗?不是我!是他?”的匹配的结果就是“是吗?不是!是?”。

另外一种写法就是指定字符范围,比如我们用[1-3]来匹配“1982,1983”,结果就是“1982,1983”;[A-D]对“BAD BOY”的匹配结果就是“BAD BOY”

除此之外,正则表达式还提供了一种补集的形式,就是把不出现在集合内的字符作为匹配对象,它的语法格式就是在左方括号的右边添加一个“^”,正则表达式[^1-3]匹配“1982,1983”的结果就是“1982,1983”。

三、元字符

元字符是被正则表达式预先保留下来的一部分字符,并有着特殊的含义。这些元字符大致可以分为两类,一类用于字符匹配,一类作为正则表达式语法的一部分来使用。如“/d”就代表了 0 至 9 之间的数字,“/s”表示空白符号,其中包括空格、制表符和换行符等,它们就是用于字符串匹配的;但是像字符集合中用到的“[”和“]”,就是被当作正则表达式语法的一部分来使用的。我们这里所介绍的都是一般的通用含义,对于这些元字符的精确含义,取决于我们所使用的软件或程序语言,因为不同的工具或程序语言都对原始的正则表达式或多或少地进行了修改或补充。

常见的用于字符匹配的元字符有“/r”——回车符、“/n”——换行符、“/t”——制表符、“/s”——空白符、“/d”——数字 0 至 9、“/w”——字母数字与下划线的组合。其中,还有一组匹配内容恰好与“/s”、“/d”、“/w”相反的 “/S”、“/D”、“/W”,如“/S”,就是与非空白字符相匹配的。

四、匹配任意字符的“.”

在正则表达式中,“.”的匹配范围最广泛,它几乎能与所有的字符相匹配,但换行符除外。所以,它相当于Unix下的[^/n]和Windows下的[^/r/n]

再次提醒一下,我们这里介绍的内容是最通用的基本含义,虽然“.”不能与换行符匹配,但在有些程序语言中,如 Java,就可以通过一种 Pattern.DOTALL 的匹配模式来让“.”与换行符相匹配,下面一段话是JavaDoc中的一段原文:

In dotall mode, the expression . matches any character, including a line terminator. By default this expression does not match line terminators. — 在 dotall 模式下,表达式 . 与任意字符匹配,包括行终结符。该表达式在默认情况下是不与行终结符相匹配的。

五、边界

边界不与任何字符相匹配,但它们能够与位置相匹配,如果不在指定位置的话,即使内容都正则表达式相符,也是不能成功匹配的。边界分为词边界和行边界两种,符号分别是/b^$

当我们要匹配与单词 cat 一致的字符串时,可以直接用cat,但是匹配的结果“Concat the word cat and dog.”并不能令我们满意。如果加上词界限定,用/bcat/b来进行匹配,效果就很明显—“Concat the word cat and dog.”,“/b”的作用就是要确保“cat”必须是一个独立单词。

行边界分为行的起始边界“^”和行的终止边界“$”。要与字符串“beginning of line border”的起始字符“b”相匹配的话,就可以使用^b,结果就是“begining of line border”。

六、重复匹配

在实际应用中,我们常常需要反复使用某个正则表达式样式,比如说要匹配电话号码的格式为0123-88888888,如果不使用正则表达式的重复匹配功能时,我们所编写的正则表达式将是/d/d/d/d-/d/d/d/d/d/d/d/d,显然,这样是很繁琐的,并且要求我们在使用中要十分小心,一不小心遗漏了一个/d,那将是件很麻烦的事情。

幸运的是,正则表达式中为我们提供了重复匹配的功能,重新改写上面的正则表达式为/d{4}-/d{8},一下子就简洁了许多。

花括号只是重复匹配功能一种形式,还有诸如“?”、“*”和“+”等重复匹配形式,它们的含义分别为:匹配零次或一次、匹配零次或更多次、匹配一次或更多次。

七、贪婪式与懒惰式

与重复匹配密切相关的一个概念就是重复匹配的模式:贪婪式和懒惰式。从书面意义上看,贪婪式就是匹配尽可能多的字符,而懒惰式当然是越少越好了。我们现在用字符串“ABC123”做个例子,首先构造使用了重复匹配功能的正则表达式ABC/d+,这时匹配的结果就是“ABC123”;如果换成ABC/d+?的话,匹配的结果就是“ABC123”。这下明白了吧,字符“+”使前面的“/d”不断的重复,在贪婪模式下,只要有满足匹配条件的,引擎就会进行下一次匹配操作,直到最后一次无法找到匹配内容时才善罢甘休;相比之下,懒惰模式下的正则表达式是很容易得到满足的,只要有一个满足匹配条件的内容,它就会立即终止匹配操作,返回结果。

八、选择

有时候,我们要匹配的内容不是很固定,这就需要提供多个备选方案。在正则表达式中“|”就能帮助我们实现按这样的效果。字符串“Superman can swim, run and fly!”用swim|run|fly进行匹配的结果就是“Superman can swim, run and fly!”

九、捕获组与逆向引用

对于词组“look down upon”和“look down on”来说,它们的含义相同,如果我们要写一个同时匹配这两个词组的正则表达式该怎么做呢?难道是look down upon|look down on?当然不是!在正则表达式中,有一种称为捕获组的语法,它能让我们把某个样式作为一个独立的单元来进行处理,这样就能对它使用各种限定修饰符,如“?”、“*”、“+”和花括号等。所以,look down (up)?on才是正确匹配词组“look down upon”和“look down on”的正则表达式;当然,这也不是唯一一个简洁的写法,我们还可以用“选择”编写look down (upon|on)来进行匹配。

使用圆括号时可以创建捕获组,捕获组的作用是把匹配到的内容“记忆”下来,这样我们就能利用逆向引用获得满足匹配条件的内容。

利用捕获组就能让我们使用逆向引用,更加灵活方便地进行样式匹配操作。但是这种灵活性是我们用更多的计算机资源所换取的,如果仅仅是为了进行匹配,并没有要使用逆向引用的需求时,完全可以取消捕获组。改写上面的正则表达式为look down (?:up)?on

十、断言

当我们要按照某一定条件来匹配一个目标字符串时,就可以使用断言。断言的作用是确保要匹配的内容的前方或后方必须是或不是我们指定的内容。

比如要找到所有那些以字符串“anti-”开头的所有单词,首先编写正则表达式anti-/b/w+/b,这时匹配字符串“anti-imperialism, anti-consumerism, anti-aircraft, anti-semitism, anti-fertilizin”的结果就是“anti-aircraft, anti-semitism, anti-fertilizin”。现在我们使用后向断言重新编写正则表达式(?<=anti-)/b/w+/b,匹配的结果就是“anti-aircraft, anti-semitism, anti-fertilizin”。

从例子可以看出,断言部分的正则表达式虽然也参与字符串匹配,但它并不把自身作为匹配结果的一部分。

<!-- InstanceEndEditable -->
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics