Java正则表达式
在开发中遇到匹配查找替换字符串的时候,如果仅仅使用纯编码的方式解决,往往会浪费程序员的时间和精力,因此这时候就需要正则表达式来解决。
正则表达式是一种可以用于模式匹配和替换的规范,一个正则表达式就是有普通的字符以及特殊的字符组成的文字模式,它用以描述在查找文字主体时匹配的一个或多个字符串。
正则表达式常见符号
方括号("[]"):方括号里面指定看起来有意义的字符,方括号里面可以参与匹配,匹配单个字符
或符号("|"):匹配一组字符。例如匹配"java",使用,"j(a|e|i|o|u|av)a"。
否符号("^"):例如[^a]匹配不是a的字符
空白符号:假设匹配日期"August 20, 2015",
[a-z]+ \s+ [0-9]{1,2}, \s*[0-9]{4}
[a-z]+表示 月份值,取值为a-z中的字母,有可能一个或多个
\s+ 表示中间可能出现的空格
[0-9]{1,2}表示月份内的日期,0-9中的数字,可能一个或两个
\s* 表示中间可能出现的空格
[0-9] 表示年份,由0-9中四个数字组成
其中\s可以匹配所有的空符号,包括Tab字符。
如果匹配正确,我们想取出其中某个值,可以使用(),例如想提取出年份[a-z]+ \s+ [0-9]{1,2}, \s*([0-9]{4}) 在调用相关的API来解决
表示匹配次数的符号
* 表示0次或者多次
+ 1次或者多次
? 0次或者1次
{n} 恰好n次
{n,m} 从n次到m次
常用字符
\d匹配0-9的数字 等价于[0-9]
\D匹配任意不是数字的字符 等价于[^0-9]
\w匹配单独字母数字下划线 等价于[a-zA-Z_0-9]
\W匹配任意不是字母,数字,下划线的字符 等价于[^a-zA-Z_0-9]
\s匹配任意空白字符 等价于[\t\n\f\r]
\S匹配任意非空白字符 等价于[^\t\n\f\r]
接下来说说java中的应用
java.util.regex 是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包。
包括两个类 Pattern和Matcher。
Pattern 一个 Pattern 是一个正则表达式经编译后的表现模式。
Matcher 一个 Matcher 对象是一个状态机器,它依据 Pattern 对象做为匹配模式对字符串展开匹配检查。
首先来介绍一下Pattern类:
Pattern的方法如下:
static Pattern compile(String regex) 将给定的正则表达式编译并赋予给Pattern类
static Pattern compile(String regex, int flags) 同上,但增加flag参数的指定,可选的flag参数包括:CASE INSENSITIVE,MULTILINE,DOTALL,UNICODE CASE, CANON EQ
int flags() 返回当前Pattern的匹配flag参数.
Matcher matcher(CharSequence input) 生成一个给定命名的Matcher对象
static boolean matches(String regex, CharSequence input) 编译给定的正则表达式并且对输入的字串以该正则表达式为模开展匹配,该方法适合于该正则表达式只会使用一次的情况,也就是只进行一次匹配工作,因为这种情况下并不需要生成一个Matcher实例。
String pattern() 返回该Patter对象所编译的正则表达式。
String[] split(CharSequence input) 将目标字符串按照Pattern里所包含的正则表达式为模进行分割。
String[] split(CharSequence input, int limit) 作用同上,增加参数limit目的在于要指定分割的段数,如将limi设为2,那么目标字符串将根据正则表达式分为割为两段。
接下来介绍一下Matcher
Matcher方法如下:
Matcher appendReplacement(StringBuffer sb, String replacement) 将当前匹配子串替换为指定字符串,并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个StringBuffer对象里。
StringBuffer appendTail(StringBuffer sb) 将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。
int end() 返回当前匹配的子串的最后一个字符在原目标字符串中的索引位置 。
int end(int group) 返回与匹配模式里指定的组相匹配的子串最后一个字符的位置。
boolean find() 尝试在目标字符串里查找下一个匹配子串。
boolean find(int start) 重设Matcher对象,并且尝试在目标字符串里从指定的位置开始查找下一个匹配的子串。
String group() 返回当前查找而获得的与组匹配的所有子串内容
String group(int group) 返回当前查找而获得的与指定的组匹配的子串内容
int groupCount() 返回当前查找所获得的匹配组的数量。
boolean lookingAt() 检测目标字符串是否以匹配的子串起始。
boolean matches() 尝试对整个目标字符展开匹配检测,也就是只有整个目标字符串完全匹配时才返回真值。
Pattern pattern() 返回该Matcher对象的现有匹配模式,也就是对应的Pattern 对象。
String replaceAll(String replacement) 将目标字符串里与既有模式相匹配的子串全部替换为指定的字符串。
String replaceFirst(String replacement) 将目标字符串里第一个与既有模式相匹配的子串替换为指定的字符串。
Matcher reset() 重设该Matcher对象。
Matcher reset(CharSequence input) 重设该Matcher对象并且指定一个新的目标字符串。
int start() 返回当前查找所获子串的开始字符在原目标字符串中的位置。
int start(int group) 返回当前查找所获得的和指定组匹配的子串的第一个字符在原目标字符串中的位置。
下面看个程序帮助理解
实例程序:
public void isEmail(String email){ String input = email; // 检测输入的 EMAIL 地址是否以 非法符号"."或"@"作为起始字符 Pattern p = Pattern.compile("^\\.|^\\@"); Matcher m = p.matcher(input); if (m.find()){ System.err.println("EMAIL 地址不能以'.'或'@'作为起始字符"); } // 检测是否以"www."为起始 p = Pattern.compile("^www\\."); m = p.matcher(input); if (m.find()) { System.out.println("EMAIL 地址不能以'www.'起始"); } // 检测是否包含非法字符 p = Pattern.compile("[^A-Za-z0-9\\.\\@_\\-~#]+"); m = p.matcher(input); StringBuffer s = new StringBuffer(); boolean result = m.find(); boolean deletedIllegalChars = false; while(result) { // 如果找到了非法字符那么就设下标记 deletedIllegalChars = true; // 如果里面包含非法字符如冒号双引号等,那么就把他们消去,加到 s 里面 m.appendReplacement(s, ""); result = m.find(); } m.appendTail(s); input = s.toString(); if (deletedIllegalChars) { System.out.println("输入的 EMAIL 地址里包含有冒号、逗号等非法字符,请修改"); System.out.println("您现在的输入为 : "+email); System.out.println("修改后合法的地址应类似 : "+input); } }