< 标记方向,这个符号说明是放在目标内容左边。
! 标记不匹配pattern,这符号说明目标内容的左边或右边,不能匹配pattern。
String s = "<Data ss:Type=\"String\">内容13</Data>";
如下正则报错:* repetition not allowed inside lookbehind
s = s.replaceAll("(?<=<Data.+?>).+(?=</Data>)", "789");
原因:Java中正则表达式后行断言的限制,不能在后行模式中使用 * 或 + 限定符,允许有限制长度{1,1000},这里1000可以根据自己实际情况修改。
改成如下:
s = s.replaceAll("(?<=<Data.{1,1000}?>).+(?=</Data>)", "789");
运行结果:<Data ss:Type="String">789</Data>
(pattern)
匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。
(?:pattern)
非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分时很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
String s = "123industry456industries789";
Pattern p = Pattern.compile("industr(?:y|ies)");//(?:pattern)
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println(m.group());// 结果:industry、industries
}
p = Pattern.compile("industr(y|ies)");//(pattern)
m = p.matcher(s);
while (m.find()) {
System.out.println(m.group());// 结果:industry、industries
}
测试结果发现不要?:效果一样
(?=pattern)
非获取匹配,正向肯定预查(包含,后面),在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern)
非获取匹配,正向否定预查(不包含,后面),在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。
(?<=pattern)
非获取匹配,反向肯定预查(包含,前面),与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
(?<!pattern)
非获取匹配,反向否定预查(不包含,前面),与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。
示例:在一段文本中找出手机号,但是防止订单号干扰,即要求手机号前后不能有数字。
订单号:202109103154636545636 ,手机号码:18888888888。联系地址:xxx。
public static void main(String[] args) {
String s;
Pattern p;
Matcher m;
// Pattern p = Pattern.compile("(?<!\\d)1\\d{10}(?!\\d)");//手机号1开头,总共11位,并且手机号前后都不能是数字。
// 1、手机号必须是1开头,总共11位
p = Pattern.compile("1\\d{10}");
s = "18888888888";
m = p.matcher(s);
if (m.find()) {
System.out.println(m.group());// 结果:18888888888
}
// 2、手机号必须是1开头,总共11位,并且手机号前面不能是数字
p = Pattern.compile("(?<!\\d)1\\d{10}");
s = "a18888888888";
m = p.matcher(s);
if (m.find()) {
System.out.println(m.group());// 结果:18888888888
}
s = "918888888888";
m = p.matcher(s);
if (m.find()) {
System.out.println(m.group());// 结果:空
}
// 3、手机号必须是1开头,总共11位,并且手机号后面不能是数字
p = Pattern.compile("1\\d{10}(?!\\d)");
s = "18888888888b";
m = p.matcher(s);
if (m.find()) {
System.out.println(m.group());// 结果:18888888888
}
s = "188888888889";
m = p.matcher(s);
if (m.find()) {
System.out.println(m.group());// 结果:空
}
// 4、手机号必须是1开头,总共11位,并且手机号前面和后面都不能是数字
p = Pattern.compile("(?<!\\d)1\\d{10}(?!\\d)");
s = "a18888888888b";
m = p.matcher(s);
if (m.find()) {
System.out.println(m.group());// 结果:18888888888
}
s = "918888888888b";
m = p.matcher(s);
if (m.find()) {
System.out.println(m.group());// 结果:空
}
s = "a188888888889";
m = p.matcher(s);
if (m.find()) {
System.out.println(m.group());// 结果:空
}
}
1、不以XX开头
String s = "AA12345";
Pattern p = Pattern.compile("[^(AA)]\\w+");
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println(m.group());
}
运行结果:12345
2、以XX开头:
String s = "AA12345";
Pattern p = Pattern.compile("(?<=AA)\\w+");
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println(m.group());
}
运行结果:12345
3.不以XX结尾
String s = "12345AA";
Pattern p = Pattern.compile("\\w+[^(AA)]");
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println(m.group());
}
运行结果:12345
4.以XX结尾
String s = "12345AA";
Pattern p = Pattern.compile("\\w+(?=AA)");
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println(m.group());
}
运行结果:12345