Java正则表达式匹配不到结果的解决

 更新时间:2021年2月23日 00:00  点击:1333

如下所示:

String str = "\uFEFF<?xml version=\"1.0\" encoding=\"utf-8\"?><Response xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><Header ShouldRecordPerformanceTime=\"false\" Timestamp=\"2018-6-25 21:24:03\" RequestID=\"2c4d0b24-fd48-4a92-a2d8-c66793df2059\" ResultCode=\"Success\" AssemblyVersion=\"2.9.5.0\" RequestBodySize=\"0\" SerializeMode=\"Xml\" RouteStep=\"1\" Environment=\"pro\" /><SSPATResponse><Result>0</Result><FareDetail /><Price>0</Price><ErrCode>102</ErrCode><DetailInfo>Send:APPLOCK\n" +
    "Rev:\n" +
    "可用资源锁定成功, 60 秒内没有输入指令资源将被Buk收回\n" +
    "Send:IG\n" +
    "Rev:\n" +
    "NO PNR\n" +
    "Send:\n" +
    "SS:AA186/N/27JUN18/PEKORD/NN1;\n" +
    "Rev:\n" +
    "AA 186 N 27JUN PEKORD NN1 WL OPEN \n" +
    "UNABLE TO SELL.PLEASE CHECK THE AVAILABILITY WITH \"AV\" AGAIN\n" +
    "Send:IG\n" +
    "Rev:</DetailInfo><PatOfficeno>SHA717</PatOfficeno></SSPATResponse><ResponseStatus><Timestamp xmlns=\"http://soa.ctrip.com/common/types/v1\">2018-06-25T21:24:03.4535624+08:00</Timestamp><Ack xmlns=\"http://soa.ctrip.com/common/types/v1\">Success</Ack></ResponseStatus></Response>";
 
String regex = "<DetailInfo>((.|\\n")*?)</DetailInfo>";

str为要匹配的字符串(是传入的),regex为正则表达式

目的是匹配出<DetailInfo>标签中的内容

在本地测试时可以匹配出来,但是在线上就不行。

真的是百思不得其解……

后来认真比对了一下线上传入的str和本地复制过来的str,发现了了一个微小的不同

线上传入的str行分隔符是\r\n,而复制粘贴到本地之后都变成了\n

而我的正则表达式中只匹配了\n的情况,因此出现这样的bug

提醒自己要注意系统之间的差别,win上的行分隔符是\n,而Linux是\r\n

为了能适配所有的环境,可以直接用System.lineSeparator()来替代,当然也可以把表达式写成这样(

<DetailInfo>((.|\\n|\\r\\n")*?)</DetailInfo>

补充:Java正则表达式匹配的坑

今天在判断字符串是否存在某个字符串,直接用String.matches(regex),死活匹配不出来,在线正则工具用了很多都是可以的,后面找到问题,总结一下,防止再次踩坑。

一、前提#

java中判断一段字符串中是否包含某个字符串的方式:

1、#

String.matches(regex);

阅读源码发现,这个方法本质是调用了Pattern.matches(regex, str),而该方法调Pattern.compile(regex).matcher(input).matches()方法,而Matcher.matches()方法试图将整个区域与模式匹配,如果匹配成功,则可以通过开始、结束和组方法获得更多信息。

即这个方法会在表达式前后加上$(regex$),是对这个字符串全匹配

而不会只匹配其中的子串,如果只想匹配子串,则需要表达式匹配整段

2、#

Pattern.compile(regex).matcher(str).find()

Matcher.find()方法则是仅仅进行匹配字串的方法

如果不想使用全局匹配则可以使用Matcher.find()方法

二、附源码#

1、String.matches(regex)#

String.matches(regex)

public boolean matches(String regex) {
    return Pattern.matches(regex, this);
}
Pattern.matches(regex, this)

public static boolean matches(String regex, CharSequence input) {
  Pattern p = Pattern.compile(regex);
  Matcher m = p.matcher(input);
  return m.matches();
}

2、Matcher.find()#

Pattern.compile

public static Pattern compile(String regex) {
    return new Pattern(regex, 0);
}
Pattern.matcher

public Matcher matcher(CharSequence input) {
    if (!compiled) {
      synchronized(this) {
        if (!compiled)
          compile();
      }
    }
    Matcher m = new Matcher(this, input);
    return m;
}

Matcher.find()

public boolean find() {
    int nextSearchIndex = last;
    if (nextSearchIndex == first)
      nextSearchIndex++;
    // If next search starts before region, start it at region
    if (nextSearchIndex < from)
      nextSearchIndex = from;
    // If next search starts beyond region then it fails
    if (nextSearchIndex > to) {
      for (int i = 0; i < groups.length; i++)
        groups[i] = -1;
      return false;
    }
    return search(nextSearchIndex);
}

三、总结#

各个匹配的优缺点都有,大家可以按需选择

如果仅仅只需要获取字符串中是否包含某个字符串,还是用Matcher.find()比较方便

以上为个人经验,希望能给大家一个参考,也希望大家多多支持猪先飞。如有错误或未考虑完全的地方,望不吝赐教。

[!--infotagslink--]

相关文章

  • Java实现经典游戏复杂迷宫

    这篇文章主要介绍了如何利用java语言实现经典《复杂迷宫》游戏,文中采用了swing技术进行了界面化处理,感兴趣的小伙伴可以动手试一试...2022-02-01
  • java 运行报错has been compiled by a more recent version of the Java Runtime

    java 运行报错has been compiled by a more recent version of the Java Runtime (class file version 54.0)...2021-04-01
  • 在java中获取List集合中最大的日期时间操作

    这篇文章主要介绍了在java中获取List集合中最大的日期时间操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
  • PHP正则匹配img及标签各属性值(匹配图片函数)

    有一个项目要获取页面中所有img标签中的图片地址,这里我们使用到了preg_match_all正则函数,然后看我下面的一些参数即可实现了。 例 代码如下 复制代码 ...2016-11-25
  • 教你怎么用Java获取国家法定节假日

    这篇文章主要介绍了教你怎么用Java获取国家法定节假日,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下...2021-04-23
  • Java如何发起http请求的实现(GET/POST)

    这篇文章主要介绍了Java如何发起http请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-31
  • PHP正则表达式取双引号内的内容

    取双引号内的内容我们如果一个字符串中只有一个可以使用explode来获得,但如果有多个需要使用正则表达式来提取了,具体的例子如下。 写程序的时候总结一点经验,如何只...2016-11-25
  • 浅谈Java与C#的一些细微差别

    说起C#和Java这两门语言(语法,数据类型 等),个人以为,大概有90%以上的相似,甚至可以认为几乎一样。但是在工作中,我也发现了一些细微的差别...2020-06-25
  • 解决Java处理HTTP请求超时的问题

    这篇文章主要介绍了解决Java处理HTTP请求超时的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-29
  • 一个关于JS正则匹配的踩坑记录

    这篇文章主要给大家介绍了一个关于JS正则匹配的踩坑记录,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-13
  • java 判断两个时间段是否重叠的案例

    这篇文章主要介绍了java 判断两个时间段是否重叠的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
  • java 画pdf用itext调整表格宽度、自定义各个列宽的方法

    这篇文章主要介绍了java 画pdf用itext调整表格宽度、自定义各个列宽的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-31
  • 超简洁java实现双色球若干注随机号码生成(实例代码)

    这篇文章主要介绍了超简洁java实现双色球若干注随机号码生成(实例代码),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-02
  • Java生成随机姓名、性别和年龄的实现示例

    这篇文章主要介绍了Java生成随机姓名、性别和年龄的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-01
  • PHP正则表达式之捕获组与非捕获组

    今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到C#和Java中有对正则捕获组的特殊用法,搜索关键词有PHP时竟然没有相关内容,自己试了一下,发现在PHP中也是可行的,于是总结一下,分享的同...2015-11-08
  • php 验证只能输入汉字、英语、数字的正则表达式

    正则表达式是一门非常有用的并且进行模糊判断的一个功能了,我们下面来看通过正则来验证输入汉字、英语、数字,具体如下。 收藏了正则表达式。可以验证只能输入数...2016-11-25
  • java正则表达式判断前端参数修改表中另一个字段的值

    这篇文章主要介绍了java正则表达式判断前端参数修改表中另一个字段的值,需要的朋友可以参考下...2021-05-07
  • Java使用ScriptEngine动态执行代码(附Java几种动态执行代码比较)

    这篇文章主要介绍了Java使用ScriptEngine动态执行代码,并且分享Java几种动态执行代码比较,需要的朋友可以参考下...2021-04-15
  • Java开发实现人机猜拳游戏

    这篇文章主要介绍了Java开发实现人机猜拳游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-03
  • 常用的日期时间正则表达式

    常用的日期时间正则表达式 下面收藏了大量的日期时间正则匹配函数,包括分钟,时间与秒都能达到。 正则表达式 (?n:^(?=d)((?<day>31(?!(.0?[2469]|11))|30(?!.0?2)|29(...2016-11-25