java-正则表达式
Java——正则表达式
正则表达式的作用?
正则表达式是用一串字符串来描述的一个匹配规则,使用正则表达式可以快速判断给定的字符串是否符合匹配规则,避免编写繁琐的逻辑判断代码。
比如:如何判断字符串是否是有效电话号码?如果使用Java判断语句进行逻辑的判断估计没个二十行代码是出不来的。但是使用正则表达式一行就可以表示判断了。
正则表达式可以用于任何语言(Java、python、C/C++),在Java中,java.util.regex包内置了正则表达式引擎。
语法:str.matches(regex)
注意:在Java中,\符号是Java的转义符,所以在Java中使用正则表达式转义符时用\\来表示,比如想匹配“1”,则用\\d。
正则表达式需要注意区分大小写。
模糊匹配:
精确匹配实际上用处不大,大多数情况下是模糊匹配。
. 匹配一个任意字符(换行符\n除外),比如正则表达式a.c可以匹配“abd”、“a&c”,但是它不能匹配“ac”,“a&&c”;
\d 匹配0-9中任意一个数字,比如正则表达式00\d可以匹配“008”、“001”;
\w 匹配一个字母、数字或下划线,比如正则表达式java\w可以匹配“javac”、“java9”、“java_”;
\s 匹配一个空格字符,包括tab键,比如正则表达式s\sa可以匹配“s a”;
\D 匹配一个非数字字符,比如正则表达式s\D可以匹配“sa”;
\S 匹配一个非\s的字符;
\W 匹配一个非\w的字符;
重复匹配:
* 匹配任意个字符,包括0个字符,比如正则表达式A\d*可以匹配“A”、“A1”、“A123”;
+ 匹配至少一个字符,比如正则表达式A\d+可以匹配“A2”、“A123”;
? 匹配0个或1个字符,比如正则表达式A\d?可以匹配“A”、“A2”;
{n} 匹配指定n个字符,比如正则表达式A\d{1}可以匹配“A1”、“A2”;
{n,} 至少匹配n个字符,比如正则表达式a{2,}可以匹配“aa”、“aaa”;
{0,n} 最多匹配n个字符,比如正则表达式a{0,2}可以匹配空、“a”、“aa”;
{n,m} 匹配指定范围个数的字符,比如正则表达式a{2,3}可以匹配“aa”、“aaa”;
匹配开头和结尾:
^n 匹配以n开头的字符,比如正则表达式^1可以匹配“12”、“1q”;
n$ 匹配以n结尾的字符,比如正则表达式a\d$可以匹配“a1”、“c2”;
匹配指定范围:
[12345] 匹配12345当中的任意一个字符,比如正则表达式a[123]可以匹配“a2”、“a3”;
[1-9] 匹配1~9当中的任意一个字符;
[a-z] 匹配a~z当中的任意一个字符;
[A-Z] 匹配A~Z当中的任意一个字符;
[^a-z] 匹配除a~z之外的任意一个字符;
或匹配:
| 两个用|连接的正则表达式都成立,比如正则表达式ab|AB可以匹配“ab”、“AB”;
分组匹配:
比如我们想要匹配字符串learn java、learn php、learn go,一个最简单的正则表达式是learn\sjava|learn\sphp|learn\sgo,但是这个表达式太复杂了,可以把公共部分提取出来,然后用(...)把子规则括起来表示成learn\s(java|php|go);
案例:使用正则表达式分组获取区号-电话号,并将它们分别存入数据库中。
第一步:编写正则表达式:\\d{3,4}\\-\\d{6,8};
第二步:将正则表达式按存入规则进行分组:(\\d{3,4})\\-(\\d{6,8});
第三步:提取子串,必须引入java.util.regex包,用Pattern.compile("regex")方法匹配并在括号中填写正则表达式;
第四步:匹配后获得一个Matcher对象,必须判断Matcher对象是否匹配成功;
第五步:如果匹配成功从Matcher.group(index)防回子串。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
String s12="011-12345678";
Pattern pa=Pattern.compile("(\\d{3,4})\\-(\\d{7,8})");
Matcher ma=pa.matcher(s12);
if (ma.matches()) {
String area=ma.group(1);
String tel=ma.group(2);
System.out.println(area);//011
System.out.println(tel);//12345678
}else {
System.out.println("匹配失败");
}
什么是贪婪匹配和非贪婪匹配?请看实例。
如,给定一个字符串表示的数字,判断该数字末尾0的个数,
“123000”,该字符串的正则表达式为(\d+)(0*),可实际上使用\d+就可以表示“123000”,这是因为正则表达式默认使用贪婪匹配。
贪婪匹配:
任意一个正则表达式规则,它总是尽可能的向后匹配,因此\d+就足以把“123000”表示出来。
但是使用贪婪匹配的话就无法知道末尾0的个数了,这时就需要非贪婪模式救场了。
非贪婪模式匹配:
为了让\d+变得不那么贪婪,可以在其后面添加?,(\d+?)(0*)即可表示非贪婪模式的正则规则,这时0*就可以匹配到“000”了,后面再用分组的方法即可得出0的个数。
String s13="123000";
Pattern pa1=Pattern.compile("(\\d+)(0*)");
Matcher ma1=pa1.matcher(s13);
if (ma1.matches()) {
String st1=ma1.group(1);
String st2=ma1.group(2);
System.out.println("st1>>>"+st1);//st1>>>123000
System.out.println("st2>>>"+st2);//st2>>>
}else {
System.out.println("匹配失败");
}
Pattern pa2=Pattern.compile("(\\d+?)(0*)");
Matcher ma3=pa2.matcher(s13);
if (ma3.matches()) {
String st1=ma3.group(1);
String st2=ma3.group(2);
System.out.println("st1>>>"+st1);//st1>>>123
System.out.println("st2>>>"+st2);//st2>>>000
System.out.println(st2.length());//3
}else {
System.out.println("匹配失败");
}
断言:
(?=表达式)正向先行断言,表示位置右侧必须能匹配表达式,比如“我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你”要求取出“喜欢你”,这时表达式就可以写“喜欢(?=你)”,表示“喜欢”右边必须匹配“你”;
(?!表达式)反向先行断言,表示位置右侧不能匹配表达式,比如“我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你”要求取出“喜欢”后面没有“你”,这时表达式就可以写“喜欢(?!你)”,表示匹配“喜欢”右边(后面)没有“你”的字符;
(?<=表达式)正向后行断言,表示所在位置左侧必须匹配表达式,比如正则表达式“我(?<=喜欢)”表示匹配“我喜欢”字符,“喜欢”左侧(前面)必须有“我”;
(?<!表达式)反向后行断言,表示所在位置左侧不能匹配表达式,比如要求取出“喜欢”两个字符,要求“喜欢”前面没有“我”,可以用正则表达式“(?<!我)喜欢”表示。
分割字符串:
使用正则表达式分割字符串可以实现更加灵活的功能。String.split()方法中传入正则表达式,比如:“a b c”.split("\\s");>>>{"a","b","c"}。这种场景适用于用户不规范的输入,将这些不规范的输入通过合适的正则表达式提取出来,只保留规范的输入。
搜索字符串:
获取到Matcher对象后,不需要调用Matches()方法,因为匹配整个串肯定放回false,而是反复调用find()方法,在整个串中搜索能匹配上\\WO\\W规则的子串,并打印出来。这种方法比String.indexof()方法要灵活得多,因为我们搜索的规则是3个字符:中间必须是哦,,前后两个必须是字符[a-zA-Z0-9]。
String s14="the quick brown fox jumps over the lazy dog.";
Pattern pa3=Pattern.compile("\\wo\\w");
Matcher ma4=pa3.matcher(s14);
if (ma4.find()) {
String sub=s14.substring(ma4.start(),ma4.end());//row
}
替换字符串:
使用正则表达式替换字符串可以直接调用string.replaceAll(),它的第一个参数是正则表达式,第二个参数是待替换的字符串。如下实例:
String s15="The quick\t\t brown fox jumps over the lazy dog.";
String s16=s15.replaceAll("\\s+"," ");
System.out.println(s16);
//The quick brown fox jumps over the lazy dog.
返向引用:
把搜索到的指定字符串按照规则替换,比如前后各加一个<b>xxx<b>,这个时候,使用replaceAll()的时候,我们传入的第二个参数可以使用$1、$2来返向引用匹配到的子串。如下实例:
String s17="the quick brown fox jumps over the lazy dog.";
String s18=s17.replaceAll("\\s([a-z]{4})\\s"," <b>$1</b> ");
System.out.println(s18);
//the quick brown fox jumps <b>over</b> the <b>lazy</b> dog.
作者:×不知该怎么√ 收藏一直进行,学习从未开始!地址https://www.cnblogs.com/hqh2021/p/17015520.html