00 09Java高级之正则表达式

1 认识正则表达式

通过之前一系列分析可以发现,String是一个非常万能的类型,因为String不仅支持各种字符串的处理操作,也支持有向各个数据类型转换的功能,所以在项目的开发之中,只要是用户输入的信息基本上都用String表示。于是在向其他数据类型转换的时候,为了保证转换的正确性,往往要对其进行一些复杂的验证处理,那么这种情况下,如果只是单纯的依靠String类中的方法是非常麻烦的。

现在假设有一个字符串要求你判断字符串是否由数字所组成,如果由数字所组成则将其变为数字并进行乘法计算。
范例:

package cn.victor.demo;

import java.text.NumberFormat;
import java.text.ParseException;

public class DateDemo {

	public static void main(String[] args) throws ParseException {
		String str = "123";
		if(isNumber(str)) {
			long n = Integer.parseInt(str);
			System.out.println(n * 2);
		}
		
	}
	
	public static boolean isNumber(String str) {
		char[] chars = str.toCharArray();
		for(int i = 0; i < chars.length; i++) {
			if( chars[i] < '0' || chars[i] > '9' ) {
				return false;
			}
		}
		
		return true;
	}
}


实际上这种验证的功能是非常简单的,但是这如此简单的功能却需要开发者编写大量的程序逻辑代码,那么如果是更加复杂的验证呢?那么在这样的情况下,对于验证来讲最好的做法就是利用正则表达式来完成。
范例:使用正则表达式实现同样的效果

package cn.victor.demo;

import java.text.NumberFormat;
import java.text.ParseException;

public class DateDemo {

	public static void main(String[] args) throws ParseException {
		String str = "123";
		if(str.matches("\\d+")) {
			long n = Integer.parseInt(str);
			System.out.println(n * 2);
		}
		
	}
}


正则表达式最早是从Perl语言里面发展而来的,而后在JDK 1.4以前如果需要使用到正则表达式的相关定义,则需要单独引入其它jar文件,但是从JDK 1.4之后,正则已经默认被JDK所支持,并且提供有java.util.regex开发包,同时针对于String类也进行了一些修改,使其有方法直接支持正则处理。

使用正则最大的特点在于方便进行验证处理,以及方便进行复杂字符串的修改处理。

2 常用正则标记

如果要想进行正则的处理操作,那么就首先需要对常用的正则标记有所掌握,从JDK 1.4开始提供有java.util.regex开发包,这个包里面提供有一个Pattern程序类,在这个程序类里面定义有所有支持的正则标记。
(1)【数量:单个】字符匹配
|——任意字符:表示由任意字符组成
|——\\:匹配“\”;
|——\n:匹配换行;
|——\t:匹配制表符;
(2)【数量:单个】字符集(可以从里面任选一个字符)
|——[abc]:表示可能是字母a、b、c中的任意一个字符;
|——[\^abc]:表示不是字母a、b、c中的任意一个;
|——[a-zA-Z]:表示由一个任意字母所组成,不区分大小写;
|——[0-9]:表示由一位数字组成。
(3)【数量:单个】简化的字符集
|——.:表示任意的字符;
|——\d:等价于范围[0-9]
|——\D:等价于范围[^0-9]
|——\s:匹配任意的一位空格,可能是空格、换行、制表符;
|——\S:匹配任意的非空格数据;
|——\w:匹配字母、数字、下划线,等价于[a-zA-Z_0-9]
|——\W:匹配非字母、数字、下划线,等价于[^a-zA-Z_0-9]
(4)边界匹配
|——^:匹配边界开始;
|——$:匹配边界结束;
(5)数量表示,默认情况下只有添加上了数量单位才可以匹配多位字符。
|——表达式?:该正则可以出现0次或1次。
|——表达式*:该正则可以出现0次、1次或多次;
|——表达式+:该正则可以出现1次或多次;
|——表达式{n}:表达式的长度正好为n次;
|——表达式{n,}:表达式的长度为n次以上;
|——表达式{n,m}:表达式的长度为n~m次;
(6)逻辑表达式:可以连接多个正则:
|——表达式X表达式Y:X表达式之后紧跟上Y表达式。
|——表达式X|表达式Y:有一个表达式满足即可。
|——(表达式):为表达式设置一个整体描述,可以为整个描述设置数量单位。

3 String类对正则的支持

在进行正则表达式大部分处理情况下都会基于String类来完成,并且在String类里面提供有如下操作方法:

No. 方法名称 类型 描述
01 public boolean matches​(String regex) 普通 将指定字符串进行正则判断
02 public String replaceAll​(String regex, String replacement) 普通 替换全部
03 public String replace​(char oldChar, char newChar) 普通 替换首个
04 public String[] split​(String regex) 普通 正则拆分
05 public String[] split​(String regex, int limit) 普通 正则拆分

下面通过一些具体得范例来对正则的使用进行说明。
范例:实现字符串的替换(删除非字母与数字)

package cn.victor.demo;

public class DateDemo {

	public static void main(String[] args) {
		String str = "328d$%$(fdf32(*&c34f34c24334gfg34c324c&crfgdsfg^%^$324csdsd##";
		String replstr = str.replaceAll("[^a-zA-Z0-9]", "");
		System.out.println(replstr);
		
	}
}


范例:实现字符串的拆分(按数字拆分)

package cn.victor.demo;

public class DateDemo {

	public static void main(String[] args) {
		String str = "328d$%$(fdf32(*&c34f34c24334gfg34c324c&crfgdsfg^%^$324csdsd##";
		String replstr[] = str.split("\\d+");
		for(int i = 0; i < replstr.length; i++) {
			System.out.println(replstr[i]);
		}
		
	}
}


在正则处理的时候对于拆分与替换的操作相对容易一些,但是比较麻烦的是数据验证部分。
范例:判断一个数据是否为小数,如果是小数则将其变为double类型

package cn.victor.demo;

public class DateDemo {

	public static void main(String[] args) {
		String str = "23";
		System.out.println(str.matches("\\d+(\\.\\d+)?"));
	}
}


范例:判断一个字符串是否由日期组成,如果是由日期所组成则将其转为Date类型

package cn.victor.demo;

import java.text.ParseException;
import java.text.SimpleDateFormat;

public class DateDemo {

	public static void main(String[] args) throws ParseException {
		String str = "1999-08-21";
		if(str.matches("\\d{4}-\\d{2}-\\d{2}"))
		{
			System.out.println(new SimpleDateFormat("yyyy-MM-dd").parse(str));
		}
	}
}


正则不能判断具体含义,只能对格式进行判断处理。
范例:判断给定的电话号码是否正确?
(1)电话号码:51283346,\\d{7,8}
(2)电话号码:01051283346,(\\d{3,4})?\\d{7,8}
(3)电话号码:(010)-51283346,((\\d{3,4})|(\\(\\d{3,4}\\))-)?\\d{7,8}

package cn.victor.demo;

import java.text.ParseException;
import java.text.SimpleDateFormat;

public class DateDemo {

	public static void main(String[] args) throws ParseException {
		String str = "(010)-5128331";
		System.out.println(str.matches("((\\d{3,4})|(\\(\\d{3,4}\\)))?-?\\d{7,8}"));
	}
}


既然已经可以使用正则进行验证了,那么下面就可以利用其来实现一个email地址格式的验证。
范例:验证email格式
(1)email的用户名可以由字母数字_ 所组成;
(2)email的域名可以由字母数字_- 所组成;
(3)域名的后缀必须是:.cn.com.net.com.cn.gov

package cn.victor.demo;

public class DateDemo {

	public static void main(String[] args) {
		String str = "[email protected]";
		System.out.println(str.matches("[^_]\\w+@[\\w-]+\\.(com|cn|com.cn|edu|gov)"));
	}
}


现在这几种正则的匹配处理操作是最常用的几种处理形式。

4 java.util.regex包支持

虽然在大部分情况下都可以利用String类实现正则的操作,但是也有一些情况下需要使用到java.util.regex开发包中提供的正则处理类,在这个包里面一共定义有两个类:Pattren(正则表达式编译)、Matcher(匹配)。
1、Pattern类
(1)Pattern类提供有正则表达式的编译处理支持:public static Pattern compile​(String regex)
(2)同时也提供有字符串的拆分操作支持:public String[] split​(CharSequence input)

package cn.victor.demo;

import java.util.regex.Pattern;

public class DateDemo {

	public static void main(String[] args) {
		String str = "1s2s3s4";
		Pattern pat = Pattern.compile("s");
		String[] resultset = pat.split(str);
		for(int i = 0; i < resultset.length; i++) {
			System.out.println(resultset[i]);
		}
	}
}


2、Matcher类,实现了正则匹配的处理类,这个类的对象实例化依靠Pattern类完成。
(1)Pattern类提供的方法:public Matcher matcher​(CharSequence input)
当获取了Matcher类的对象之后就可以利用该类中的方法进行如下操作:
(1)正则匹配:public boolean matches()

package cn.victor.demo;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DateDemo {

	public static void main(String[] args) {
		String str = "123";
		Pattern pat = Pattern.compile("\\d+");
		Matcher mac = pat.matcher(str);
		System.out.println(mac.matches());
	}
}


(2)字符串替换:public String replaceAll​(String replacement)

package cn.victor.demo;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DateDemo {

	public static void main(String[] args) {
		String str = "1s2s3";
		Pattern pat = Pattern.compile("s");
		Matcher mac = pat.matcher(str);
		System.out.println(mac.replaceAll(""));
	}
}


如果纯粹的是以拆分、替换、匹配三种操作为例,根本用不到java.util.regex开发包,只依靠String类就都可以实现了。但是Matcher类里面提供有一种分组的功能,而这种分组的功能是String不具备的。

package cn.victor.demo;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DateDemo {

	public static void main(String[] args) {
		String str = "select * from table values(#{dept},#{no},#{name})";
		Pattern pat = Pattern.compile("#\\{\\w+\\}");
		Matcher mac = pat.matcher(str);
		while(mac.find()) {
			System.out.println(mac.group(0).replaceAll("\\W+", ""));
		}
	}
}


java.util.regex开发包,如果不是进行一些更为复杂的正则处理是很难使用到的,而String类所提供的功能只适合于正则的基本操作。

发布了87 篇原创文章 · 获赞 11 · 访问量 2989

猜你喜欢

转载自blog.csdn.net/weixin_43762330/article/details/104770176
00