Java正则表达式匹配不到结果的解决
如下所⽰:
String str = "\uFEFF<?xml version=\"1.0\" encoding=\"utf-8\"?><Response xmlns:xsd=\"/2001/XMLSchema\" xmlns:xsi=\"/2001/XMLSchema-instance\"><Header ShouldRecordPerformanceTime=\"false\" Timestamp=\"2018    "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=\"ip/common/types/v1\">2018-06-25T21:24:03.4535624+08:00</Timestamp><Ack xmlns=\"ip/common/ 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),⽽该⽅法调Patternpile(regex).matcher(input).matches()⽅法,⽽Matcher.matches()⽅法试图将整个区域与模式匹配,如果匹配成
功,则可以通过开始、结束和组⽅法获得更多信息。
即这个⽅法会在表达式前后加上$(regex$),是对这个字符串全匹配
⽽不会只匹配其中的⼦串,如果只想匹配⼦串,则需要表达式匹配整段
2、#
Patternpile(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 = Patternpile(regex);
Matcher m = p.matcher(input);
return m.matches();
}
2、Matcher.find()#
Patternpile
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()⽐较⽅便
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。如有错误或未考虑完全的地⽅,望不吝赐教。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。