`
hcx_2008
  • 浏览: 117468 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

JAVA正则表达式高级用法(分组与捕获)

    博客分类:
  • J2SE
阅读更多
正则表达式在字符串处理中经常使用,关于正则简单的用法相信有一点程序基础的人都懂得一些,这里就不介绍简单基础了。这里主要讲解一下在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引用只是引用文本而不是表达式。

非捕获组 

      以 (?) 开头的组是纯的非捕获 组,它不捕获文本 ,也不针对组合计进行计数。就是说,如果小括号中以?号开头,那么这个分组就不会捕获文本,当然也不会有组的编号,因此也不存在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代码片段如下:

1. Pattern p = Pattern.compile( "(?<!c)a(\\d+)bd " );
2. Matcher m = p.matcher( "da12bka3434bdca4343bdca234bm" );
3.  while (m.find()){
4.   System.out.println(m.group( 1 )); //我们只要捕获组1的数字即可。结果 3434
5.   System.out.println(m.group(0)); // 0组是整个表达式,看这里,并没有提炼出(?<!c)的字符 。结果 a3434bd
6. }
    可以看到,非捕获组,最后是不会返回结果的,因为它本身并不捕获文本。

正则表达式功能其实非常强大,这里只是对高级用法的简单探讨。有兴趣的朋友和本人共同讨论。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/hcx_2008/archive/2010/08/21/5827850.aspx
分享到:
评论

相关推荐

    精通正则表达式~~~

    使用正则表达式匹配文本... 38 向更实用的程序前进... 40 成功匹配的副作用... 40 错综复杂的正则表达式... 43 暂停片刻... 49 使用正则表达式修改文本... 50 例子:公函生成程序... 50 举例:修整股票价格....

    C# 最全的日期正则表达式,没有之一

    考虑到这个正则表达式仅仅是用作验证,所以捕获组没有意义,只会占用资源,影响匹配效率,所以可以使用非捕获组来进行优化。 ^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2...

    一个java正则表达式工具类源代码.zip(内含Regexp.java文件)

    * Summary of regular-expression constructs 正则表达式结构简介: * Construct Matches * Characters 字符: * x The character x x 字符 x * \\ The ...

    正则表达式30分钟入门教程

    如果能使用算术比较的话,或许能简单地解决这个问题,但是正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择,字符类来描述一个正确的IP地址:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|...

    浅谈Java中正则表达式的优化方法

    获取每次使用引起小损失的分组。如果你实际并不需要获取一个分组内的文本,那么就使用非捕获分组。

    PHP正则表达式之捕获组与非捕获组

    今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到C#和Java中有对正则捕获组的特殊用法,搜索关键词有PHP时竟然没有相关内容,自己试了一下,发现在PHP中也是可行的,于是...

    named-regexp:为Java 56正则表达式命名的捕获组

    命名正则表达式 这个轻量级的库在Java 5/6(和Android)中增加了对支持。 这是来自Google Code的项目的分支(当前处于非活动状态)。 用法 您可以对Java 7中的命名捕获组使用相同的构造(即(?&lt;name&gt;patt)等),如...

    javascript中使用正则表达式删除前后空格的方法

    js正则表达式删除字符串前后空格 String.prototype.trim=function(){ var reSpace=/^\s*(.*?)\s*$/; return this.replace(reSpace,”$1″); }; 让我们分析一下第二行的正则表达式 ^ 行开始 \s* 匹配字符前面的所有...

    (?:pattern)的用法 表示此组不被捕获

    java 正则表达式 (?:pattern)的用法 表示此组不被捕获

    MultiRegExp:一个简单的Java脚本对象,可让您获取正则表达式中许多组的文本和字符串位置

    一个简单的Java脚本对象,使您可以获取正则表达式中许多组的文本和字符串位置。 用法 var exp = new MultiRegExp(/([[az] +)(?:\ s | _)*([0-9] +)/ i); exp.exec(“ test_53”); //将返回{0:{index:...

    named-regexp, Java 5/6 正规表达式的命名捕获组.zip

    named-regexp, Java 5/6 正规表达式的命名捕获组 命名正则表达式 这个轻量级库增加了 5/6 ( 在Android上) 中命名为捕获组( )的支持。这是来自( 当前处于非活动状态)的名为regexp的的fork的。用法可以以使用( 。例如...

    editplus 代码编辑器html c++ jsp css

    这个也算正则表达式的用法,其实仔细看正则表达式应该比较简单,不过既然有这个问题提出,说明对正则表达式还得有个认识过程,解决方法如下 解决: 在替换对话框中,启用“正则表达式”复选框 在查找内容里面输入...

    EditPlus 2整理信箱的工具

    这个也算正则表达式的用法,其实仔细看正则表达式应该比较简单,不过既然有这个问题提出,说明对正则表达式还得有个认识过程,解决方法如下 解决: 在替换对话框中,启用“正则表达式”复选框 在查找内容里面输入...

    Editplus 3[1].0

    这个也算正则表达式的用法,其实仔细看正则表达式应该比较简单,不过既然有这个问题提出,说明对正则表达式还得有个认识过程,解决方法如下 解决: 在替换对话框中,启用“正则表达式”复选框 在查找内容里面输入...

    JAVA_API1.6文档(中文)

    java.util.regex 用于匹配字符序列与正则表达式指定模式的类。 java.util.spi java.util 包中类的服务提供者类。 java.util.zip 提供用于读写标准 ZIP 和 GZIP 文件格式的类。 javax.accessibility 定义了用户...

    java实现别踩白块儿源码-JavaCode:我专门介绍以下主题:Java基本数据类型,声明语句,表达式语句,导入类库,用户输入之外,检查有效

    Java线程,正则表达式,使用Java Swing及其组件的图形用户界面(GUI),GUI事件处理,ChangeListener,JOptionPane,组合框,列表框,JLists,DefaultListModel,将JScrollpane与JList,JSpinner,JTree,Flow,...

    Java 1.6 API 中文 New

    java.util.regex 用于匹配字符序列与正则表达式指定模式的类。 java.util.spi java.util 包中类的服务提供者类。 java.util.zip 提供用于读写标准 ZIP 和 GZIP 文件格式的类。 javax.accessibility 定义了用户界面...

    java api最新7.0

    java.util.regex 用于匹配字符序列与正则表达式指定模式的类。 java.util.spi java.util 包中类的服务提供者类。 java.util.zip 提供用于读写标准 ZIP 和 GZIP 文件格式的类。 javax.accessibility 定义了用户界面...

    计算器源码下载java-dev-tools:一款应用中最受欢迎的软件开发工具

    使用以下方法构建本机应用程序: mvn clean client:build 或下载最新版本。 从 JDK 11 开始,JavaFX 不是 Java SDK 的一部分。 特征 暗/亮模式。 工具清单 JSON 编辑器 带有突出显示的 JSON 漂亮打印。 JSON 验证。 ...

Global site tag (gtag.js) - Google Analytics