java正则表达式使用

2022-07-29 10:18:13

正则表达式

  • 是什么: 正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串
  • 干什么:正则主要用于字符串中 为方便字符串操作 ,很多地方不使用正则表达式也能达到目的,但是可能麻烦很多。
  • 怎么用:在java中的标准使用如下:
//编译正则表达式,这样子可以重用模式。Pattern p=Pattern.compile("a*b");// 用模式检查字符串Matcher m= p.matcher("aaaaab");//检查匹配结果boolean b= m.matches();

上面的使用太繁琐,一般使用场景我们只需要匹配检查一次即可。所以可以省略为如下方式:

boolean b = Pattern.matches("a*b", "aaaaab");

另外正则运用在字符串上,上面那样普通使用还是麻烦,因此在字符串对象里提供快速调用的方法(matches/split/replace), 如上面的matches只需要这样:

"aaaaab".matches("a*b")

字符串matches和Pattern.matches的源码如下,可以发现其实内部还是用了第一种方式的。

//String对象成员matches方法publicbooleanmatches(String regex){returnPattern.matches(regex,this);}//Pattern的matches方法publicstaticbooleanmatches(String regex,CharSequence input){Pattern p=Pattern.compile(regex);Matcher m= p.matcher(input);return m.matches();}
  • 字符串的操作主要有四种,匹配、切割、替换、获取,我们接下来分别说明,其中涉及到 “组” 的概念

一,匹配

  • 匹配规则, 如:
#字符类[abc] a、b 或 c(简单类)[^abc] 任何字符,除了 a、b 或 c(否定)[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)[a-z&&[def]] d、e 或 f(交集)[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)
  • 更多具体的匹配规则可以在 java.util.regex.Pattern 的文档里找到, 这些规则基本是通用的.即,其他语言的也是这样子的形式. 另外在java中,需要 " \ "的匹配符,需要加多一个 " \ " 进行转义.
  • 匹配规则是基础, 先匹配, 才能对匹配进行切割,替换,获取操作
  • 常见如检查匹配邮箱,手机号码等. 简单检查匹配手机号码如下:
String regex="1[358]\\d{9}";boolean flag="15322510408".matches(regex);

二,切割

  • String[] str = string.split(regex) ;如下简单例子:
//按一个或多个空格切割String name="aaaaa     _haha";String regex=" +";String[] strs= name.split(regex);
  • 例子2: 根据重复的字符进行切割, 例如."abctttttttcdemmmmmmfglllllll-------"切割结果为[abc,cde,fg], 这里就需要引入组的概念了.
    - 组: 可以简单理解为, 把匹配的规则 当成一个变量 来使用 ,组的概念大部分也是通用的.
    • 用"()" 即定义了一个匹配组
    • 捕获组可以通过从左到右计算其开括号来编号. 例如,在表达式regex中((A)(B(C)))中,存在四个这样的组:
      • ((A)(B(C)))
      • (A)
      • (B(C))
      • (C)
    • 编号为0的组代表整个表达式. 可以理解为, 组的号码是从1开始, 并且从左到右增加,
    • 要使用到组,引用组方式:\\1(第一个\用来转义)或者$1。因此上面按重复切割代码如下:
    • 组的另外说明:在regex里\\1引用,不在regex$1引用,如:String[] strs = name.split("(.)\\1+")String result = name.replaceAll("(\\d{3})", "$1")
//按重复字符切割String name="abctttttttcdemmmmmmfglllllll-------";String regex="(.)\\1+";String[] strs= name.split(regex);

三,替换

  • 字符串中的替换方法如下:
    • string.replace(char oldChar, char newChar)string.replace(CharSequence target, CharSequence replacement)替换单个字符,不使用到正则
    • string.replaceAll(String regex, String replacement)替换字符串,使用到正则
    • string.replaceFirst(String regex, String replacement)替换匹配的第一个字符串,使用到正则
  • 替换也有组的概念, 例如,要将上面的重复字符替换为单个字符,即结果为abctcdemfgl-, 代码如下
String name="abctttttttcdemmmmmmfglllllll-------";String regex="(.)\\1+";String result= name.replaceAll(regex,"$1");
  • 还有,把手机号码的中间思维替换为****, 做法类似。
  • 方法1:分成三组
String name="13800138000";String regex="(\\d{3})(\\d{4}) (\\d{4})";String result= name.replaceAll(regex,"$1****$3");
  • 方法2:分成两组
String name="13800138000";String regex="(\\d{3})\\d{4}(\\d{4})";String result= name.replaceAll(regex,"$1****$2");

四,获取

  • 获取的方式,string对象里没有直接支持。因此要直接使用到Pattern和Matcher对象

  • 做法如下:

    • 获得pattern对象,pattern静态方法complie 返回pattern对象
    • pattern 的matcher方法返回matcher匹配器对象
    • [可选操作] 调用 matcher对象 的 matches(str)返回true或false以此来判断是否有匹配的字符串
    • matcher.find() , 指针会移动到下一个匹配的字符串,如果有返回true. 通过**matcher.group();**等方法 获取当前指针匹配的字符串
    • find方法说明文档:尝试查找与该模式匹配的 < 输入序列的下一个子序列 >。 此方法从匹配器区域的开头开始,如果该方法的前一次调用成功了并且从那时开始匹配器没有被重置,则从以前匹配操作没有匹配的第一个字符开始。如果匹配成功,则可以通过 start、end 和 group 方法获取更多信息。
  • 例如上面要获取手机号码中间四位。

String name="13800138000";String regex="(\\d{3})(\\d{4})(\\d{4})";Pattern pattern=Pattern.compile(regex);Matcher matcher= pattern.matcher(name);String result=null;if(matcher.find()){//如果需要取所有,可以使用while//取第二组的数据。
			result= matcher.group(2);}

p.s 正则在java等的api文档中写得很详细了,有什么细节,例如匹配规则等建议直接看文档,会更详细,

  • 作者:既看方向也看行动
  • 原文链接:https://blog.csdn.net/dansam/article/details/88840858
    更新时间:2022-07-29 10:18:13