开发过程中的真实场景

A报文

<?xml version="1.0" encoding="utf-8"?>
<PACKET><HEAD><SERVICE_NAME>seeYou</SERVICE_NAME></HEAD><BODY><CONTENT><![CDATA[<?xml version="1.0" encoding="utf-8"?><PACKET><![CDATA[nice to meet you!]]></PACKET>]]></CONTENT></BODY>
</PACKET>

嵌套在A报文中的B报文

<?xml version="1.0" encoding="utf-8"?>
<PACKET>
<![CDATA[nice to meet you!
]]>
</PACKET>

场景

我得到A报文,后需要解析提取B报文转发给目标系统.

而现有解析代码PatternTool.java如下:

package kingtool;import java.util.regex.Matcher;
import java.util.regex.Pattern;public class PatternTool {/*** 从regex表达式中提供对应的值* @author King*/public static String parsePattern(String regex, String content ,int groupNum) {String ret = "";String str = "";String output ="";try {Pattern p = Pattern.compile(regex);Matcher m = p.matcher(content);if (m.find()) {for(int i = 0 ; i  <= m.groupCount() ; i ++){if(i == 0){}else{str = m.group(i);output = String.format("解析得正则表达式%s中group(%d)匹配的值\n",regex,i);System.out.println(output);System.out.println(str);}}ret = m.group(groupNum);System.out.println("返回第"+groupNum+"组匹配到的内容:\n"+ret);}else{System.out.println("未解析到正则表达式"+regex+"匹配的的值\n");}} catch (Exception e) {e.printStackTrace();}return ret;}public static void main(String[] args) {String content = FileTool.readStringFromFile("D://c.txt", "GBK"    );//希望匹配<CONTENT>.*<![CDATA[.*]]>.*</CONTENT>String regex = "<CONTENT>(.*)<!\\[CDATA\\[(.*)\\]\\]>(.*)</CONTENT>";String ret = parsePattern(regex,content,2);}
}

解析后,打印结果如下(并非最终想要的B报文):

文件 D://c.txt存在与否?: true
读到的文件内容如下:
<?xml version="1.0" encoding="utf-8"?><PACKET>    <HEAD>        <SERVICE_NAME>seeYou</SERVICE_NAME>    </HEAD>    <BODY>        <CONTENT>            <![CDATA[                 <?xml version="1.0" encoding="utf-8"?>                 <PACKET>                 <![CDATA[                    nice to meet you!                 ]]>                </PACKET>            ]]>        </CONTENT>            </BODY></PACKET>
解析得正则表达式<CONTENT>(.*)<!\[CDATA\[(.*)\]\]>(.*)</CONTENT>中group(1)匹配的值<![CDATA[                 <?xml version="1.0" encoding="utf-8"?>                 <PACKET>
解析得正则表达式<CONTENT>(.*)<!\[CDATA\[(.*)\]\]>(.*)</CONTENT>中group(2)匹配的值nice to meet you!                 ]]>                </PACKET>
解析得正则表达式<CONTENT>(.*)<!\[CDATA\[(.*)\]\]>(.*)</CONTENT>中group(3)匹配的值返回第3组匹配到的内容:

现在来分析以上原因:

1.因为正则默认是贪婪的(全取模式,能吃多少是多少),所以第一个(.*)先取

然后一点一点从尾部吐出来,直到匹配(<!\[CDATA\[(.*)\]\]>)就停止吐字符,至此 group(1) 匹配结束.

2. 现在来匹配第二个(.*),老规矩先全取

然后一个一个吐字符,直到遇到]]>

3. 最后来匹配第三个(.*),老规矩先全取

直到遇到</CONTENT>停下

最终,这完全不是我们希望看到的匹配结果 nice to meet you! ]]> </PACKET>

解决方案: 加个?变成懒猫模式即可

把PatternTool.java中main主函数的正则匹配式regex中的第一个括号中加一个?,变成懒猫模式

public static void main(String[] args) {String content = FileTool.readStringFromFile("D://c.txt", "GBK"    );//希望匹配<CONTENT>.*<![CDATA[.*]]>.*</CONTENT>String regex = "<CONTENT>(.*?)<!\\[CDATA\\[(.*)\\]\\]>(.*)</CONTENT>";String ret = parsePattern(regex,content,2);}

解析后,打印结果如下(是最终想要的B报文):

文件 D://c.txt存在与否?: true
读到的文件内容如下:
<?xml version="1.0" encoding="utf-8"?><PACKET>    <HEAD>        <SERVICE_NAME>seeYou</SERVICE_NAME>    </HEAD>    <BODY>        <CONTENT>            <![CDATA[                 <?xml version="1.0" encoding="utf-8"?>                 <PACKET>                 <![CDATA[                    nice to meet you!                 ]]>                </PACKET>            ]]>        </CONTENT>            </BODY></PACKET>
解析得正则表达式<CONTENT>(.*?)<!\[CDATA\[(.*)\]\]>(.*)</CONTENT>中group(1)匹配的值解析得正则表达式<CONTENT>(.*?)<!\[CDATA\[(.*)\]\]>(.*)</CONTENT>中group(2)匹配的值<?xml version="1.0" encoding="utf-8"?>                 <PACKET>                 <![CDATA[                    nice to meet you!                 ]]>                </PACKET>
解析得正则表达式<CONTENT>(.*?)<!\[CDATA\[(.*)\]\]>(.*)</CONTENT>中group(3)匹配的值返回第2组匹配到的内容:<?xml version="1.0" encoding="utf-8"?>                 <PACKET>                 <![CDATA[                    nice to meet you!                 ]]>                </PACKET>            

现在来分析以上原因:

1.因为加了?后,正则变成了懒猫模式(特别地懒,能不吃就不吃),所以第一个(.*?)先取

然后一点一点吃字符进来,直到匹配(<!\[CDATA\[(.*)\]\]>)就停止吃字符,至此 group(1) 匹配结束.

2. 现在来匹配第二个(.*),老规矩先全取

然后一个一个吐字符,直到遇到]]>

3. 最后来匹配第三个(.*),老规矩先全取

直到遇到</CONTENT>停下

最终,这就是我们希望看到的匹配结果 :

<?xml version="1.0" encoding="utf-8"?><PACKET><![CDATA[nice to meet you!]]></PACKET>

总结:

正则默认贪婪模式 : 能取多少是多少

加了?后变成懒猫模式 : 能不取就尽量不取

本文原创,请转明出处,by 金墨痴.

转载于:https://www.cnblogs.com/whatlonelytear/p/5764298.html

正则表达式高级用法【原】相关推荐

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

    2019独角兽企业重金招聘Python工程师标准>>> 正则表达式在字符串处理中经常使用,关于正则简单的用法相信有一点程序基础的人都懂得一些,这里就不介绍简单基础了.这里主要讲解一下 ...

  2. python3.7正则表达式语法_python3正则表达式的几个高级用法

    python3正则表达式的几个高级用法 一. 概述 本文举例说明python3正则表达式的一些高级级法,主要是各类分组,可应用于 1.复杂网页文件中的有用数据 例如,采用爬虫技术取得网页后,对网页内任 ...

  3. js replace不改变原str_总结javascript replace高级用法

    详解javascript replace高级用法 在前端与后台交互的时候我们通常都需要将后台传递的数据绑定到html中,这个绑定数据的方式我们通常是使用jQuery或者使用原生的innerHTML进行 ...

  4. vim的高级用法配置以及在系统中如何获取帮助

    vim的高级用法配置以及在系统中如何获取帮助 1 vim的三种模式 1.1 使用方法 1.2 vim模式 2 vim工作的基本配置 2.1 临时设定(set设定) 2.2 永久设定方式 3 搜索 4 ...

  5. sed的基本用法和高级用法

    sed 的详细用法 sed:stream editor 流编辑器 sed的工作模式:sed是一个行文本编辑器,默认每次处理文本中所匹配到一行内容到模式空间,然后用后面的命令进行操作,操作完成之后,会把 ...

  6. Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

    之前在<关于 WEB/HTTP 调试利器 Fiddler 的一些技巧分享>中系统的介绍过 Fiddler 的原理与一些常见技巧,但那篇文章只是入门科普,并不深入,今天要介绍到的内容相对更加 ...

  7. python基础和第三方库 笔记(python基础完结包括高级用法,第三方库持续更新中...)

    python基础 注:本笔记面向有一定基础的人 本笔记是本人快速复习python过程中记录的,不适合零基础的人学习python的主工具,可以作为辅工具,本笔记记录了入门阶段常用操作,如有错误的地方,希 ...

  8. Python进阶:切片的误区与高级用法

    众所周知,我们可以通过索引值(或称下标)来查找序列类型(如字符串.列表.元组...)中的单个元素,那么,如果要获取一个索引区间的元素该怎么办呢? 切片(slice)就是一种截取索引片段的技术,借助切片 ...

  9. Git log高级用法

    格式化Log输出 首先,这篇文章会展示几种git log格式化输出的例子.大多数例子只是通过标记向git log请求或多或少的信息. 如果你不喜欢默认的git log格式,你可以用git config ...

最新文章

  1. MongoDB简单操作
  2. 3年国奖、一作9篇SCI,完美逆袭的中大博士坦言自己也曾濒临挂科
  3. 关于java中Math的一些用法
  4. Detach Volume 操作 - 每天5分钟玩转 OpenStack(55)
  5. MM32F3277 MicroPython 的定时器功能
  6. 将多个图片转换成PDF文件-img2pdf
  7. matlab序列谱分析,基于MATLAB序列谱分析及FFT实现快速卷积.pdf
  8. 基本排序(C语言版)
  9. 【CuteJavaScript】Angular6入门项目(1.构建项目和创建路由)
  10. ON DELETE CASCADE和ON UPDATE CASCADE
  11. CSS的块级元素和内联元素,以及float
  12. robot framework -重点记录
  13. 《DNS与BIND(第5版)》——第10章 高级功能10.1 地址匹配列表和ACL
  14. 太阳当空照-Windows服务化方式instsrv与srvany
  15. 微信企业消息推送方案
  16. 初始MySQL数据库
  17. DROOPYCTF WALKTHROUGH
  18. 已斥资250亿!东京奥运会的AI黑科技能否如期亮相?
  19. JQuery获取选中的元素(单选框复选框)及其他等
  20. 怎么做抖音故障艺术风格人物照片效果

热门文章

  1. 游戏中的颜色:深度解析游戏设计工具
  2. 1个人,耗时2年半,这款大型仙侠3D硬核ARPG是怎么做出来的?
  3. 游戏服务器端引擎——DogSE的设计
  4. 游戏中的实时水体模拟技术分享:波形叠加法与波动方程
  5. 如何用行为树开发游戏AI以及任务系统?
  6. LNMP单机高并发的简单优化
  7. python获取当前路径下所有文件
  8. scip 练习2.18
  9. 如何使用matplotlib绘制一个函数的图像
  10. 关于水晶报表的一些错误