Java 使用正则表达式
目录
正则表达式介绍
正则表达式可以用来进行文本的处理(内容匹配),相对于字符串操作来说,正则表达式特别强大,于是,他的时间开销就比字符串操作要大。通常,如果是简单的文本内容操作,那么优先使用字符串操作,只有当字符串操作起来比较困难的时候,再使用正则表达式。
正则表达式的相关概念和语法,是独立的,与编程语言没有多大的关系,所以这里就不累述正则表达式了,接下来的内容都是关于在Java中是怎么结合正则表达式的
Java使用正则表达式的最简流程
正则表达式其实就是一个带有特殊含义的字符串,这个字符串对于Java来说,也就是简单的字符串。所以Java中使用正则表达式的流程可以归结如下:
1、将正则表达式(字符串)经过Java将其进行编译一次之后,即可获得正则表达式(Pattern对象)。
2、使用编译好的正则表达式,对要进行匹配的内容(字符串)进行匹配,获得Matcher对象。
3、调用Matcher对象的一些方法即可获取匹配的结果。
package lixin.gan.test; import java.util.regex.Matcher; import java.util.regex.Pattern; public class UseRegExp { /** * 简单尝试一下正则表达式,认识一下Pattern类和Matcher类 * 使用Matcher.matches()进行整体匹配 */ public static void BasicUseRegExp_matches() { // 我们的匹配规则需要先进行编译一下,编译之后返回正则表达式 Pattern pattern = Pattern.compile("\\d{2}"); // 注意,正则表达式中转义字符的反斜线还需要加一个反斜线进行转义 // 目标字符串,要在该字符串中进行查找或者匹配 String str = "123456789"; // 利用已经编译的正则表达式,接收字符串进行匹配 Matcher matcher = pattern.matcher(str); // 123456789整体不满足\d{2} boolean matched = matcher.matches(); System.out.println(matched); // false // 调用matches()方法,尝试将字符串整个的拿去和正则表达式进行匹配, // 将整个字符串(看做整体)是否匹配 str = "55"; matcher = pattern.matcher(str); // 55整体满足\d{2} matched = matcher.matches(); System.out.println(matched); // true } /** * 使用Matcher.find()进行多次匹配 * 调用group()来获取匹配的内容 */ public static void BasicUseRegExp_find() { Pattern pattern = Pattern.compile("go{1,3}gle"); Matcher matcher = pattern.matcher("ggle gogle google gooogle goooogle"); // matcher.matches()是使用字符串整体去匹配正则表达式,且仅匹配一次 // matcher.find()表示使用正则表达式去字符串中组个匹配,可以匹配多次,每次匹配终点的下一个位置就是下一次匹配的起点 boolean matched = false; matched = matcher.find(); if (matched) { System.out.println(matcher.group()); } // gogle matched = matcher.find(); if (matched) { System.out.println(matcher.group()); } // google matched = matcher.find(); if (matched) { System.out.println(matcher.group()); } // gooogle matched = matcher.find(); if (matched) { System.out.println(matcher.group()); } // 只匹配了三次,这一次没有匹配到 // 上面的过程可以使用while循环代替 // 重新开始匹配 matcher.reset(); while(matcher.find()) { System.out.println(matcher.group()); } /* gogle google gooogle */ } /** * 使用group(num)来获取第num个子元组的匹配内容 */ public static void BasicUseRegExp_groupN() { String str = ""; str += "<a herf=\"http://www.cnblogs.com/-beyond\">寻觅beyond</a>"; str += "<a herf=\"http://www.cnblogs.com/-demo\">testDemo</a>"; Pattern pattern = Pattern.compile("<a (.*?)>(.*?)</a>"); Matcher matcher = pattern.matcher(str); while(matcher.find()) { System.out.println("group ==> " + matcher.group()); System.out.println("group(0) ==> " + matcher.group(0)); System.out.println("group(1) ==> " + matcher.group(1)); System.out.println("group(2) ==> " + matcher.group(2)); System.out.println("-------------------------------------"); } /* group ==> <a herf="http://www.cnblogs.com/-beyond">寻觅beyond</a> group(0) ==> <a herf="http://www.cnblogs.com/-beyond">寻觅beyond</a> group(1) ==> herf="http://www.cnblogs.com/-beyond" group(2) ==> 寻觅beyond ------------------------------------- group ==> <a herf="http://www.cnblogs.com/-demo">testDemo</a> group(0) ==> <a herf="http://www.cnblogs.com/-demo">testDemo</a> group(1) ==> herf="http://www.cnblogs.com/-demo" group(2) ==> testDemo ------------------------------------- */ } public static void main(String[] args) { BasicUseRegExp_groupN(); } }
使用正则表达式进行字符串替换操作
正则表达式不仅可以进行操作匹配,也可以进行替换操作。
对于字符串来说,String类本身就有两个方法可以实现替换功能:
String String.replace(Char oldChar, Char newChar); String String.replace(CharSequence target, CharSequence replacement);
同样,也提供了两个方法用来实现正则表达式替换操作:
// 只替换一次 String java.lang.String.replaceFirst(String regex, String replacement) // 替换所有符合要求的内容 String String.replaceAll(String regex, String replacement)
因为正则表达式的开销比较大,所以,如果是简单的字符串替换,建议使用字符串操作,避免使用正则表达式。
下面是两种方式的使用示例:
package lixin.gan.test; public class UseRegExpToReplace { public static void main(String[] args) { String str = "123#456#789#000"; // 将字符串中的#号,全部替换为问号 // 使用字符串的进行替换 System.out.println(str.replace('#', '?')); // 123?456?789?000 // 使用正则表达式进行替换 System.out.println(str.replaceAll("#", "?")); // 123?456?789?000 // 简单的替换尽量使用字符串操作,避免使用正则表达式 // 稍微复杂一点的,将str中的大于或等于5的数字替换为$符号 // 使用字符串的操作实现 String newStr = str.replace('5', '$'). replace('6', '$'). replace('7', '$'). replace('8', '$'). replace('9', '$'); System.out.println(newStr); // 123#4$$#$$$#000 // 使用正则表达式,很简单的一行代码 newStr = str.replaceAll("[5-9]", "\\$"); System.out.println(newStr); // // 123#4$$#$$$#000 } }
使用正则表达式进行字符串分割操作
同样的,仍旧可以使用正则表达式进行字符串分隔,使用的是下面两个方法:
// 按照传入的正则表达式,只要符合内容就切割 String[] String.split(String regex) // 只匹配limit-1次(只切割limit-1次),返回的数组包含limit个元素 String[] java.lang.String.split(String regex, int limit)
下面是实例:
package lixin.gan.test; import java.util.Arrays; public class UseRegExpToSplite { public static void main(String[] args) { String str = "123#456?789@000"; // 以#,?,@为分割符 String[] data = str.split("[#?@]"); System.out.println(Arrays.toString(data)); // [123, 456, 789, 000] data = str.split("[#?@]", 3); // 切割3-1次,返回的数组包含3个原色 System.out.println(Arrays.toString(data)); // [123, 456, 789@000] } }
拓展:使用模式修正符
模式修正符是我在学习PHP时的叫法,他的功能就是对正则表达式进行额外的补充说明,对其进行修正。比如我们要匹配有忽略大小写的字符串时,可以在编译正则表达式的时候,传入一个Pattern.CASE_INSENSITIVE即可,类似的还有其他几个修正符,具体可以看下面的示例代码:
package lixin.gan.test; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 使用模式修正符 */ public class UseModifier { /** * 忽略大小写:Pattern.CASE_INSENSITIVE */ public static void caseInsensitive() { String str = "abcxxxABC"; // 如果要加模式修正符,可以在compile的时候指定第二个参数即可 Pattern pattern = Pattern.compile("abc", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(str); while(matcher.find()) { System.out.println(matcher.group()); } // abc // ABC } /** * 多行模式:Pattern.MULTILINE */ public static void multiLine() { /** 通常情况下,默认的是单行模式,即将所有的内容都看做一行内容。 比如下面的字符串, abc123 abc456 abc789 上面的字符串在单行模式下,是这样的: abc123\nabc456\nabc789 而多行模式,就是没遇到一个换行,就真的看做一行 **/ // 单行模式 String str = "abc123\nabc456\nabc789"; Pattern pattern = Pattern.compile("^abc"); Matcher matcher = pattern.matcher(str); while(matcher.find()) { System.out.println(matcher.group()); } // abc // 使用多行模式 pattern = Pattern.compile("^abc", Pattern.MULTILINE); matcher = pattern.matcher(str); while(matcher.find()) { System.out.println(matcher.group()); } /* abc abc abc */ } public static void main(String[] args) { multiLine(); } }