java正则表达式使用

正则表达式

  • 是什么: 正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串
  • 干什么:正则主要用于 字符串中 为方便 字符串操作 ,很多地方不使用正则表达式也能达到目的,但是可能麻烦很多。
  • 怎么用:在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方法
	public boolean matches(String regex) {
        return Pattern.matches(regex, this);
    }
    //Pattern的matches方法
    public static boolean matches(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, 因此上面按重复切割代码如下:
 //按重复字符切割
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,分成三组, 方法2,分成两组
String name = "13800138000" ;
String regex ="(\\d{3}) (\\d{4}) (\\d{4})" ;
String result = name.replaceAll(regex, "$1****$3");
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文档中写得很详细了,有什么细节例如匹配规则等建议看文档,会更详细,

你可能感兴趣的:(程序,JAVA)