正则表达式从入门到精通

来源:互联网 发布:演唱会望远镜 知乎 编辑:程序博客网 时间:2024/06/03 20:17
括号表达式

  可以在一个方括号 ([ 和 ]) 中放入一个或多个单字符,来创建一个待匹配的列表。如果字符被放入括号中括起来,则该列表称为括号表达式。括号内和其他任何地方一样,普通字符代表其本身,也就是说,它们匹配输入文字中出现的一处自己。大多数特殊字符在位于括号表达式中时都将失去其含义。这里有一些例外:
  • ']' 字符如果不是第一项,则将结束一个列表。要在列表中匹配 ']' 字符,请将其放在第一项,紧跟在开始的 '[' 后面。

  • '\' 仍然作为转义符。要匹配 '\' 字符,请使用 '\\'。
  括号表达式中所包含的字符只匹配该括号表达式在正则表达式中所处位置的一个单字符。下面的 JScript 正则表达式可以匹配 'Chapter 1'、'Chapter 2'、'Chapter 3'、'Chapter 4' 以及 'Chapter 5':
  /Chapter [12345]/  在 VBScript 中要匹配同样的章节标题,请使用下面的表达式:
  "Chapter [12345]"  请注意单词 'Chapter' 及后面的空格与括号内的字符的位置关系是固定的。因此,括号表达式只用来指定满足紧跟在单词 'Chapter' 和一个空格之后的单字符位置的字符集合。这里是第九个字符位置。

  如果希望使用范围而不是字符本身来表示待匹配的字符,则可以使用连字符将该范围的开始和结束字符分开。每个字符的字符值将决定其在一个范围内的相对顺序。下面的 JScript 正则表达式包含了一个等价于上面所示的括号列表的范围表达式。
  /Chapter [1-5]/  VBScript 中相同功能的表达式如下所示:
  "Chapter [1-5]"  如果以这种方式指定范围,则开始和结束值都包括在该范围内。有一点特别需要注意的是,在 Unicode 排序中起始值一定要在结束值之前。

  如果想在括号表达式中包括连字符,则必须使用下述方法之一:
  • 使用反斜杠将其转义: [\-]
  • 将连字符放在括号列表的开始和结束位置。下面的表达式能匹配所有的小写字母和连字符: [-a-z][a-z-]
  • 创建一个范围,其中开始字符的值小于连字符,而结束字符的值等于或大于连字符。下面两个正则表达式都满足这一要求: [!--][!-~]
  同样,通过在列表开始处放置一个插入符(^),就可以查找所有不在列表或范围中的字符。如果该插入符出现在列表的其他位置,则匹配其本身,没有任何特殊含义。下面的 JScript 正则表达式匹配章节号大于 5 的章节标题:
  /Chapter [^12345]/  对 VBScript 则使用:
  "Chapter [^12345]"  在上面所示的示例中,表达式将匹配第九个位置处除1, 2, 3, 4, or 5 之外的任何数字字符。因此, 'Chapter 7' 为一个匹配,同样 'Chapter 9' 也是如此。

  上面的表达式可以使用连字符 (-) 表示。对 JScript 为:
  /Chapter [^1-5]/  或者,对 VBScript 为:
  "Chapter [^1-5]"  括号表达式的典型用法是指定对任何大写或小写字母字符或任何数字的匹配。下面的 JScript 表达式给出了这一匹配:
  /[A-Za-z0-9]/  等价的 VBScript 表达式为:
  "[A-Za-z0-9]"  限定符

  有时候不知道要匹配多少字符。为了能适应这种不确定性,正则表达式支持限定符的概念。这些限定符可以指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。

  下表给出了各种限定符及其含义的说明:

字符 描述 * 匹配前面的子表达式零次或多次。例如,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*'。 {n,m} mn 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。
  对一个很大的输入文档而言,章节数很轻易就超过九章,因此需要有一种方法来处理两位数或者三位数的章节号。限定符就提供了这个功能。下面的JScript 正则表达式可以匹配具有任何位数的章节标题:
  /Chapter [1-9][0-9]*/  下面的 VBScript 正则表达式执行同样的匹配:
  "Chapter [1-9][0-9]*"  请注意限定符出现在范围表达式之后。因此,它将应用于所包含的整个范围表达式,在本例中,只指定了从 0 到 9 的数字。

  这里没有使用 '+' 限定符,因为第二位或后续位置上并不一定需要一个数字。同样也没有使用 '?' 字符,因为这将把章节数限制为只有两位数字。在 'Chapter' 和空格字符之后至少要匹配一个数字。

  如果已知章节数限制只有99 章,则可以使用下面的 JScript 表达式来指定至少有一位数字,但不超过两个数字。
  /Chapter [0-9]{1,2}/  对 VBScript 可以使用下述正则表达式:
  "Chapter [0-9]{1,2}"  上述表达式的缺点是如果有一个章节号大于 99,它仍只会匹配前两位数字。另一个缺点是某些人可以创建一个 Chapter 0,而且仍能匹配。一个更好的用来匹配两位数的 JScript 表达式如下:
  /Chapter [1-9][0-9]?/  或者
  /Chapter [1-9][0-9]{0,1}/  对 VBScript 而言,下述表达式与上面等价:
  "Chapter [1-9][0-9]?"  或者
  "Chapter [1-9][0-9]{0,1}"  '*'、'+' 和 '?' 限定符都称之为贪婪的,也就是说,他们尽可能多地匹配文字。有时这根本就不是所希望发生的情况。有时则正好希望最小匹配。

  例如,你可能要搜索一个 HTML 文档来查找一处包含在 H1 标记中的章节标题。在文档中该文字可能具有如下形式:
  <H1>Chapter 1 – Introduction to Regular Expressions</H1>  下面的表达式匹配从开始的小于号 (<) 到 H1 标记结束处的大于号之间的所有内容。
  /<.*>/  VBScript 的正则表达式为:
  "<.*>"  如果所要匹配的就是开始的 H1 标记,则下述非贪婪地表达式就只匹配。
  /<.*?>/  或者
  "<.*?>"  通过在 '*'、 '+' 或 '?' 限定符后放置 '?',该表达式就从贪婪匹配转为了非贪婪或最小匹配。
0 0
原创粉丝点击