本文实例讲述了正则表达式教程之重复匹配。分享给大家供大家参考,具体如下:

注:在所有例子中正则表达式匹配结果包含在源文本中的【和】之间,有的例子会使用Java来实现,如果是java本身正则表达式的用法,会在相应的地方说明。所有java例子都在JDK1.6.0_13下测试通过。

一、有多少个匹配

前面几篇讲的都是匹配一个字符,但是一个字符或字符集合要匹配多次,应该怎么做呢?比如要匹配一个电子邮件地址,用之前说到的方法,可能有人会写出像\[email protected]\w\.\w这样的正则表达式,但这个只能匹配到像[email protected]这样的地址,明显是不正确的,接下来就来看看如何匹配电子邮件地址。

首先要知道电子邮件地址的组成:以字母数字或下划线开头的一组字符,后面跟@符号,再后面是域名,即用户名@域名地址。不过这也跟具体的邮箱服务提供商有关,有的在用户名中也允许.字符。

1、匹配一个或多个字符

要想匹配同一个字符(或字符集合)的多次重复,只要简单地给这个字符(或字符集合)加上一个+字符作为后缀就可以了。+匹配一个或多个字符(至少一个)。如:a匹配a本身,a+将匹配一个或多个连续出现的a;[0-9]+匹配多个连续的数字。

注意:在给一个字符集合加上+后缀的时候,必须把+放在字符集合的外面,否则就不是重复匹配了。如[0-9+]这样就表示数字或+号了,虽然语法上正确,但不是我们想要的了。

正则表达式:

分析:\w+可以匹配一个或多个字符,而子表达式(\w+\.)+可匹配像xxxx.edu.这样的字符串,而最后不会是.字符结尾,所以后面还会有一个\w+。像[email protected]这样的邮件地址也会匹配到。

2、匹配零个或多个字符

匹配零个或多个字符使用元符*,它的用法和+完全一样,只要把它放在一下字符或字符集合的后面,就可以匹配该字符(或字符集合)连续出现零次或多次。如正则表达式ab*c可以匹配ac、abc、abbbbbc等。

3、匹配零个或一个字符

匹配零个或一个字符使用元字符?。像上一篇说到的匹配一个空白行使用正则表达式\r\n\r\n,但在Unix和Linux中不需要\r,就可以使用元字符?,\r?\n\r?\n这样既可匹配windows中的空白行,也可匹配Unix和Linux中的空白行。下面来看一个匹配http或https协议的URL的例子:

文本:The URL is http://www.mikan.com, to connect securely use https://www.mikan.cominstead.

正则表达式:https?://(\w+\.)+\w+

结果:The URL is 【http://www.mikan.com】, to connect securely use 【https://www.mikan.com】 instead.

分析:这个模式以https?开头,表示?之前的一个字符可以有,也可以没有,所以它能匹配http或https,后面部分和前一个例子一样。

二、匹配的重复次数

正则表达式里的+、*和?解决了很多问题,但是:

1)+和*匹配的字符个数没有上限。我们无法为它们将匹配的字符个数设定一个最大值。

2)+、*和?至少匹配一个或零个字符。我们无法为它们将匹配的字符个数另行设定一个最小值。

3)如果只使用*和+,我们无法把它们将匹配的字符个数设定为一个精确的数字。

正则表达式里提供了一个用来设定重复次数的语法,重复次数要用{和}字符来给出,把数值写在它们中间。

1、为重复匹配次数设定一个精确值

如果想为重复匹配次数设定一个精确的值,把那个数字写在{和}之间即可。如{4}表示它前面的那个字符(或字符集合)必须在原始文本中连续重复出现4次才算是一个匹配,如果只出现了3次,也不算是一个匹配。

如前面几篇中说到的匹配页面中颜色的例子,就可以用重复次数来匹配:#[[:xdigit:]]{6}或#[0-9a-fA-F]{6},POSIX字符在java中是#\\p{XDigit}{6}。

2、为重复匹配次数设定一个区间

{}语法还可以用来为重复匹配次数设定一个区间,也就是为重复匹配次数设定一个最小值和最大值。这种区间必须以{n, m}这样的形式给出,其中n>=m>=0。如检查日期格式是否正确(不检查日期的有效性)的正则表达式(如日期2012-08-12或2012-8-12):\d{4}-\d{1,2}-\d{1,2}。

3、匹配至少重复多少次

{}语法的最后一种用法是给出一个最小的重复次数(但不必给出最大重复次数),如{3,}表示至少重复3次。注意:{3,}中一定要有逗号,而且逗号后不能有空格。否则会出错。

来看一个例子,使用正则表达式把所有金额大于$100的金额找出来:

文本:

$25.36

$125.36

$205.0

$2500.44

$44.30

正则表达式:$\d{3,}\.\d{2}

结果:

$25.36

【$125.36】

【$205.0】

【$2500.44】

$44.30

+、*、?可以表示成重复次数:

+等价于{1,}

*等价于{0,}

?等价于{0,1}

三、防止过度匹配

?只能匹配零个或一个字符,{n}和{n,m}也有匹配重复次数的上限,但是像*、+、{n,}都没有上限值,这样有时会导致过度匹配的现象。

来看匹配一个html标签的例子

文本:

Yesterday is history,tomorrow is a mystery, but today is a gift.

正则表达式:.*[Bb]>

结果:

Yesterday is 【history,tomorrow is a mystery, but today is a gift】.

分析:匹配标签(不区分大小写),[Bb]>匹配标签(不区分大小写)。但结果却不是预期的那样有三个,第一个标签之后,一直到最后一个之间的东西全部匹配出来了。

为什么会这样呢?因为*和+都是贪婪型的元字符,它们在匹配时的行为模式是多多益善,它们会尽可能从一段文本的开头一直匹配到这段文本的末尾,而不是从这段文本的开头匹配到碰到第一个匹配时为止。

当不需要这种贪婪行为时,可以使用这些元字符的懒惰型版本。懒惰意思是匹配尽可能少的字符,与贪婪型相反。懒惰型元字符只需要给贪婪型元字符加上一个?后缀即可。下面是贪婪型元字符的对应懒惰型版本:

*       *?

+       +?

{n,}   {n,}?

所以上面的例子中,正则表达式只需要改成.*?[Bb]>即可,结果如下:

history

mystery

gift

四、总结

正则表达式的真下威力体现在重复次数匹配方面。这里介绍了+、*、?几种元字符的用法,如果要精确的确定匹配次数,使用{}。元字符分贪婪型和懒惰型两种,在需要防止过度匹配的场合下,请使用懒惰型元字符来构造正则表达式。在下一篇中将会介绍位置匹配。

PS:这里再为大家提供2款非常方便的正则表达式工具供大家参考使用:

JavaScript正则表达式在线测试工具:http://tools.jb51.net/regex/javascript

正则表达式在线生成工具:http://tools.jb51.net/regex/create_reg

希望本文所述对大家正则表达式学习有所帮助。

这就是微学网-程序员之家为你提供的"正则表达式教程之重复匹配详解"希望对你有所帮助.本文来自网络,转载请注明出处:http://www.weixuecn.cn/article/12355.html

java正则表达式 匹配次数_正则表达式教程之重复匹配详解相关推荐

  1. java正则出现次数_正则表达式(二)—匹配次数的正则

    正则表达式 匹配次数的正则 在前一篇文章中,我们总结了和位置相关的正则,在这篇文章中,我们将继续学习正则表达式其它的内容. 假如现在给你一个regular_1.txt文件,让你找出含有连续2个a的行, ...

  2. java g1的并行_「g1」JVM G1详解 - seo实验室

    g1 当我们调优java程序时,通常的目标有两个: 响应能力 或者 吞吐量 响应能力 响应能力指一个程序或者系统对请求的是否能够及时响应. 比如: 一个桌面UI能多快的响应一个事件: 一个网站能够多快 ...

  3. 我的世界Java版最大村庄_我的世界19w11a:详解MC全新村庄机制,我已经准备好重开存档了!...

    已经两周没见到JAVA版的快照了,难道Mojang在憋大招么?没错,本周快照19w11a确实是憋了一个大招! 我的世界19w11a:正式版发布不远了!村庄大改完成,全新交易来袭我的世界19w11a:详 ...

  4. java 二叉树的高度_最全二叉树:完整详解二叉树的遍历以及完全二叉树等6种二叉树...

    树在数据结构中占据了非常重要的位置,尤其是二叉树.经常是在java面试中必问的一个环节,而且二叉树的应用场景真的非常普遍,需要重点掌握好. 但是一直以来,很多同学对于二叉树的掌握都是不太全面.今天我就 ...

  5. java死信队列_Spring Boot系列教程之死信队列详解

    前言 在说死信队列之前,我们先介绍下为什么需要用死信队列. 如果想直接了解死信对接,直接跳入下文的"死信队列"部分即可. ack机制和requeue-rejected属性 在项目s ...

  6. java controller注解原理_@Controller、@RestController注解区别详解

    @Controller.@RestController注解区别: @RestController 注解相当于 @Controller + @ResponseBody 合在一起的作用. 一.@Contr ...

  7. 我的世界java版记分板_我的世界计分板教程 计分板指令详解

    我的世界计分板教程 计分板指令详解.啊下面就给大家详细的介绍一下我的世界中的计分板吧!计分板的指令主要是objectives.players.teams.那下面就将这三个指令教程详细的分享一下吧!希望 ...

  8. eval 函数 java_[Java教程]eval()函数用法详解

    [Java教程]eval()函数用法详解 0 2015-12-14 11:00:26 eval()函数用法详解: 此函数可能使用的频率并不是太高,但是在某些情况下具有很大的作用,下面就介绍一下eval ...

  9. Nmap扫描教程之基础扫描详解

    Nmap扫描教程之基础扫描详解 Nmap扫描基础扫描 当用户对Nmap工具了解后,即可使用该工具实施扫描.通过上一章的介绍,用户可知Nmap工具可以分别对主机.端口.版本.操作系统等实施扫描.但是,在 ...

最新文章

  1. KALI Linux 系统安装 翻译
  2. Spring Workflow
  3. 第六届蓝桥杯JavaC组_垒骰子_详解
  4. 数据结构之字典序全排列
  5. 产品经理如何让程序员放下手中的刀?
  6. delete table 和 truncate table
  7. 深度学习 --- 优化入门三(梯度消失和激活函数ReLU)
  8. python封装成exe后运行失败_python 在编译成EXE 文件后报错 我实在是找不出原因
  9. 高质量linux c编程指南,《linux c编程指南》学习手记5
  10. centos7 “v篇n“工具
  11. The server time zone value ‘?й???????‘ is unrecognized or represents more than one time zone.
  12. 人工智能原理(学习笔记)
  13. asp.net实现无刷新ajax技术登录界面
  14. 【中亦安图】风险提醒之Oracle RAC高可用失效(2)
  15. 三极管类型及工作状态判断
  16. Android 计时器实现
  17. CoreData基础
  18. VMware设置虚拟机与物理主机处于同一网段,桥接模式
  19. 18年6月六级翻译词汇
  20. [数据库]数据库临时表

热门文章

  1. XGBoost 重要参数(调参使用)
  2. ubuntu安装小米随身wifi驱动
  3. Thinkphp使用Validate里的正则表达式验证中文名字和身份证号码
  4. Ogre 3D与材质 -----OGRE 3D 1.7 Beginner‘s Guide中文版 第七章
  5. 2019年-数字游戏
  6. break和continue语句
  7. iOS开发 调试 网络限速
  8. 手把手教你用python一键抢12306火车票(附代码)
  9. flask flask_paginate简单分页案例;网页url随着分页动态变化
  10. 神华资产注入预期或被透支