12.正则表达式:反向引用

转自:http://taoistwar.javaeye.com/blog/617639

正则表达式的最重要功能之一是存储匹配的模式的一部分以供以后重新使用的能力。您可能想起,若在正则表达式模式或模式的一部分两侧加上括号,就会导致表达式的一部分被存储到临时缓冲区中。可以通过使用非捕获元字符 ?:、?= 或 ?! 来重写捕获。

 

每个捕获的子匹配项按照它们在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。可以使用 /n 来访问每个缓冲区,其中 n 是标识特定缓冲区的一位或两位十进制数字。

 

反向引用的最简单的、最有用的应用之一,是提供查找文本中两个相同的相邻单词的匹配项的能力。以下面的句子为例:

Is is the cost of of gasoline going up up?

上面的句子很显然有多个重复的单词。如果能设计一种方法定位该句子,而不必查找每个单词的重复出现,那该有多好。下面的正则表达式使用单个子表达式来实现这一点:

//b([a-z]+) /1/b/gi

捕获的表达式,正如 [a-z]+ 指定的,包括一个或多个字母。正则表达式的第二部分是对以前捕获的子匹配项的引用,即,单词的第二个匹配项正好由括号表达式匹配。/1 指定第一个子匹配项。字边界元字符确保只检测整个单词。否则,诸如“is issued”或“this is”之类的词组将不能正确地被此表达式识别。

 

正则表达式后面的全局标记 (g) 指示,将该表达式应用到输入字符串中能够查找到的尽可能多的匹配表达式的结尾处的不区分大小写 (i) 标记指定不区分大小写。 多行标记指定换行符的两边可能出现潜在的匹配。

 

使用上面的正则表达式,下面的代码可以使用子匹配项信息,将文本字符串中的两个连续相同的单词的匹配项替换为同一单词的单个匹配项:

var ss = "Is is the cost of of gasoline going up up?./n";
var re = //b([a-z]+) /1/b/gim;       //Create regular expression pattern.
var rv = ss.replace(re,"$1");   //Replace two occurrences with one.

replace 方法内使用 $1 引用第一个保存的子匹配项。如果您有多个子匹配项,您将通过使用 $2$3 等依次引用它们。

反向引用还可以将通用资源指示符 (URI) 分解为其组件。假定您想将下面的 URI 分解为协议(ftp、http 等等)、域地址和页/路径:

http://msdn.microsoft.com:80/scripting/default.htm

下面的正则表达式提供该功能:

/(/w+):([^/:]+)(:/d*)?([^# ]*)/

第一个括号子表达式捕获 Web 地址的协议部分。该子表达式匹配在冒号和两个正斜杠前面的任何单词。

第二个括号子表达式捕获地址的域地址部分。该子表达式匹配不包括 / 或 : 字符的任何字符序列。

第三个括号子表达式捕获端口号(如果指定了的话)。该子表达式匹配冒号后面的零个或多个数字。

最后,第四个括号子表达式捕获 Web 地址指定的路径和/或页信息。该子表达式匹配 # 或空格字符之外的一个或多个字符。

将正则表达式应用到上面的 URI,各子匹配项包含下面的内容:

  • RegExp.$1 包含“http”
  • RegExp.$2 包含“msdn.microsoft.com”
  • RegExp.$3 包含“:80”
  • RegExp.$4 包含“/scripting/default.htm”

z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值