转自 http://blog.sina.com.cn/s/blog_4b9694cf0100cghj.html
正则表达式在字符串处理中经常使用,关于正则简单的用法相信有一点程序基础的人都懂得一些,这里就不介绍简单基础了。这里主要讲解一下在JAVA中实现了的正则的高级用法-分组与捕获。
对于要重复单个字符,非常简单,直接在字符后卖弄加上限定符即可,例如 a+ 表示匹配1个或一个以上的a,a?表示匹配0个或1个a。这些限定符如下所示:
X? |
X,一次或一次也没有 |
X* |
X,零次或多次 |
X+ |
X,一次或多次 |
X{n} |
X,恰好 n 次 |
X{n,} |
X,至少 n 次 |
X{n,m} |
X,至少 n 次,但是不超过 m
|
但是我们如果要对多个字符进行重复怎么办呢?此时我们就要用到分组,我们可以使用小括号"()"来指定要重复的子表达式,然后对这个子表达式进行重复,例如:(abc)? 表示0个或1个abc 这里一个括号的表达式就表示一个分组。
分组可以分为两种形式,捕获组和非捕获组。
捕获组
捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
1
((A)(B(C))) |
2
\A |
3
(B(C)) |
4
(C) |
组零始终代表整个表达式
之所以这样命名捕获组是因为在匹配中,保存了与这些组匹配的输入序列的每个子序列。捕获的子序列稍后可以通过 Back 引用在表达式中使用,也可以在匹配操作完成后从匹配器检索。
Back 引用是说在后面的表达式中我们可以使用组的编号来引用前面的表达式所捕获到的文本序列(是文本不是正则)。
例如 ([" ']).* \1 其中使用了分组,\1就是对引号这个分组的引用,它匹配包含在两个引号或者两个单引号中的所有字符串,如,"abc" 或 " ' " 或 ' " ' ,但是请注意,它并不会对" a'或者 'a"匹配。原因上面已经说明,Back引用只是引用文本而不是表达式。
注释:
上面表达式中的\1,指的是引用捕获组([" '])匹配到的文本,例如 "a' ,捕获组([" '])会先匹配双引号",\1就会引用",于是不能与 "a' 匹配。
非捕获组
以 (?) 开头的组是纯的非捕获 组,它不捕获文本,也不针对组合计进行计数。就是说,如果小括号中以?号开头,那么这个分组就不会捕获文本,当然也不会有组的编号,因此也不存在Back 引用。
在Java中,支持的非捕获组,有如下几种:
(?=X) |
X,通过零宽度的正 lookahead |
(?!X) |
X,通过零宽度的负 lookahead |
(?<=X) |
X,通过零宽度的正 lookbehind |
(?<!X) |
X,通过零宽度的负 lookbehind |
这四个非捕获组用于匹配表达式X,但是不包含表达式的文本。
(?=X ) |
零宽度正先行断言。仅当子表达式 X 在此位置的右侧匹配时才继续匹配。
例如,\w+(?=\d) 与后跟数字的单词匹配,而不与该数字匹配。此构造不会回溯。
|
(?!X) |
零宽度负先行断言。仅当子表达式 X 不在此位置的右侧匹配时才继续匹配。
例如,\w+(?!\d) 与后不跟数字的单词匹配,而不与该数字匹配。
|
(?<=X) |
零宽度正后发断言。仅当子表达式 X 在此位置的左侧匹配时才继续匹配。
例如,(?<=19)99 与跟在 19 后面的 99 的实例匹配。此构造不会回溯。
|
(?<!X) |
零宽度负后发断言。仅当子表达式 X 不在此位置的左侧匹配时才继续匹配。
例如,(?<!19)99 与不跟在 19 后面的 99 的实例匹配
|
注释:
非捕获组不带 < 表示对右侧匹配,同时整个非捕获组也必须在右边;带 < 表示对左侧匹配,同时整个非捕获组也必须在左边。
! 表示否定、非、补的意思。
<应在 ! 的前面
举例:
上面都是理论性的介绍,这里就使用一些例子来说明一下问题:
1、测试匹配性 (?<!4)56(?=9) 这里的含义就是匹配后面的文本56前面不能是4,后面必须是9组成。因此,可以匹配如下文本 5569 ,与4569不匹配。
2 、提取字符串 提取 da12bka3434bdca4343bdca234bm 提取包含在字符a和b之间的数字,但是这个a之前的字符不能是c,b后面的字符必须是d才能提取。
例如这里就只有3434这个数字满足要求。那么我们怎么提取呢?
首先我们写出提取这个字符串的表达式: (?<!c)a(\d+)bd 这里就只有一个捕获组(\d+)
JAVA代码片段如下:
-
Pattern p = Pattern.compile("(?<!c)a(\\d+)bd");
-
Matcher m = p.matcher("da12bca3434bdca4343bdca234bm");
-
while(m.find()){
-
System.out.println(m.group(1)); //我们只要捕获组1的数字即可。结果 3434
-
System.out.println(m.group(0)); // 0组是整个表达式,看这里,并没有提炼出(?<!c)的字符 。结果 a3434bd
-
}
可以看到,非捕获组,最后是不会返回结果的,因为它本身并不捕获文本。
分享到:
相关推荐
Java正则表达式是编程语言Java中的一个强大工具,用于处理字符串模式匹配和搜索替换。在Java中,正则表达式被广泛应用于数据验证、文本提取、文本替换等多个场景。这篇博文将深入探讨Java正则表达式的使用和相关API...
本资料"java_zhengze.rar"提供了对Java正则表达式的详细讲解,包括基本概念、元字符、预定义字符类以及各种匹配操作,对于Java开发者来说是一份非常实用的学习资源。 首先,我们来了解一下正则表达式的基石——元...
"天涯浪子"推荐的两款正则表达式测试工具——Regex Match Tracer 2.1.6.925和regextest,为学习和调试正则表达式提供了极大的便利。 Regex Match Tracer 是一个功能强大的正则表达式分析器,它可以帮助用户直观地...
### JAVA正则表达式——Pattern和Matcher详解 #### 一、引言 随着JDK 1.4的发布,Java终于内置了自己的正则表达式API,这对于Java开发者来说无疑是个福音,意味着不再需要依赖第三方库就能高效地处理文本数据。Java...
Java通过`java.util.regex`包中的两个核心类——`Pattern`和`Matcher`——提供了对正则表达式的支持。 1. **Pattern** 类:它负责编译正则表达式字符串为模式对象。这个模式对象可以被用来创建多个`Matcher`实例,...
精通正则表达式第三版 搜集于网络 前言..........I 第1章:正则表达式入门.... 1 解决实际问题... 2 作为编程语言的正则表达式... 4 以文件名做类比... 4 以语言做类比... 5 正则表达式的知识框架... 6 对于...
4. 分组和捕获:查看正则表达式中的分组捕获结果,便于理解复杂的匹配结构。 5. 选项设置:调整匹配模式,如忽略大小写、多行模式等,模拟不同的匹配条件。 6. 性能评估:通过执行多次匹配,分析正则表达式的运行...
AegEx520FS是一个专门为Delphi设计的正则表达式组件,它提供了与Perl、Java等语言中正则表达式功能类似的API,使得Delphi程序员可以方便地在应用程序中进行正则表达式操作。这个库通常包含了头文件、源代码以及可能...
第十一章 Java与.NET中的正则表达式应用: 最后,本章将专注于Java和.NET平台下正则表达式的使用,包括API调用、编译正则表达式、执行匹配和替换操作等,并可能包含一些平台特有功能的介绍。 通过这个压缩包的学习...
下面将详细介绍C#语言的关键特性及其在文本解析领域中的应用——正则表达式。 #### C#的关键特性 1. **面向对象**: - **类和对象**:支持面向对象编程的基本概念,如类、对象。 - **封装**:将数据和行为包装在...
后来,该理论被应用于Ken Thompson的计算搜索算法中,从而产生了正则表达式的首个实际应用——Unix中的qed编辑器。自此以后,正则表达式成为了许多基于文本的编辑器和搜索工具的重要组成部分。 #### 3. 正则表达式...
### 正则表达式介绍——IT知识精粹 正则表达式是一种强大的文本处理工具,广泛应用于各种编程语言中,用于实现模式匹配、文本搜索与替换等操作。它由一系列特殊的字符序列组成,用于描述在查找文字模式时的规则。 ...
#### Python中的正则表达式模块——re模块 在Python中,处理正则表达式的标准库是`re`模块。该模块提供了丰富的功能来创建和操作正则表达式,包括模式的编译、搜索、替换等。 ##### re模块的核心概念与功能 - **...
在“解密EditPlus的强大功能——活用正则表达式你将事半功倍.doc”文档中,可能会详细介绍如何在EditPlus这款强大的文本编辑器中利用正则表达式进行高效操作。EditPlus是一款支持多种编程语言的编辑器,其内置的正则...
在正则表达式的世界里,逆序环视(Lookbehind)是一种高级匹配技术,它允许我们检查一个字符串是否满足特定的前置条件,但不包括这些条件在最终的匹配结果中。逆序环视分为肯定逆序环视(Positive Lookbehind)和...
regularexpression=/pattern/[switch] 这个switch就有三种值 g: 全局匹配 i: 忽略大小写 gi: 全局匹配 + 忽略大小写 JScript 语言参考 ... 所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到
在网页链接抓取中,正则表达式用于定义我们希望捕获的数据格式,例如邮箱地址、电话号码或者特定的URL结构。正则表达式由一系列特殊字符和元字符组成,如`.`代表任意字符,`*`表示前面的字符可以出现零次或多次,`[]...