《Java基础知识》Java正则表达式
正则表达式定义了字符串的模式。
正则表达式可以用来搜索、编辑或处理文本。
正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。
正则表达式实例
一个字符串其实就是一个简单的正则表达式,例如 Hello World 正则表达式匹配 "Hello World" 字符串。
.(点号)也是一个正则表达式,它匹配任何一个字符如:"a" 或 "1"。
下面列出了一些正则表达式的实例及描述:
Java 正则表达式和 Perl 的是最为相似的。
java.util.regex 包主要包括以下三个类:
- Pattern 类:
pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。
- Matcher 类:
Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。
- PatternSyntaxException:
PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
import java.util.regex.*; class RegexExample1{ public static void main(String args[]){ String content = "I am noob from runoob.com."; String pattern = ".*runoob.*"; boolean isMatch = Pattern.matches(pattern, content); System.out.println("字符串中是否包含了 'runoob' 子字符串? " + isMatch); } }
运行结果:
捕获组
捕获组是把多个字符当一个单独单元进行处理的方法,它通过对括号内的字符分组来创建。
例如,正则表达式 (dog) 创建了单一分组,组里包含"d","o",和"g"。
捕获组是通过从左至右计算其开括号来编号。例如,在表达式((A)(B(C))),有四个这样的组:
- ((A)(B(C)))
- (A)
- (B(C))
- (C)
可以通过调用 matcher 对象的 groupCount 方法来查看表达式有多少个分组。groupCount 方法返回一个 int 值,表示matcher对象当前有多个捕获组。
还有一个特殊的组(group(0)),它总是代表整个表达式。该组不包括在 groupCount 的返回值中。
实例
下面的例子说明如何从一个给定的字符串中找到数字串:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class var { public static void main(String[] agrs){ // 按指定模式在字符串查找 String line = "This order was placed for QT3000! OK?"; String pattern = "(\\D*)(\\d+)(.*)"; // 创建 Pattern 对象 Pattern r = Pattern.compile(pattern); // 现在创建 matcher 对象 Matcher m = r.matcher(line); if (m.find()) { System.out.println("Found value: " + m.group(0) ); System.out.println("Found value: " + m.group(1) ); System.out.println("Found value: " + m.group(2) ); System.out.println("Found value: " + m.group(3) ); } else { System.out.println("NO MATCH"); } } }
运行结果:
正则表达式语法
在 Java 中,\\ 表示:我要插入一个正则表达式的反斜线,所以其后的字符具有特殊的意义。
所以,在其他的语言中(如Perl),一个反斜杠 \ 就足以具有转义的作用,而在 Java 中正则表达式中则需要有两个反斜杠才能被解析为其他语言中的转义作用。也可以简单的理解在 Java 的正则表达式中,两个 \\ 代表其他语言中的一个 \,这也就是为什么表示一位数字的正则表达式是 \\d,而表示一个普通的反斜杠是 \\\\。
Matcher 类的方法
案例分析:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class var { private static final String REGEX = "\\bcat\\b"; //设置规则 private static final String INPUT = "cat cat cat cattie cat"; //需要被分析和匹配的字符串 public static void main(String[] agrs){ Pattern p = Pattern.compile(REGEX); Matcher m = p.matcher(INPUT); // 获取 matcher 对象 int count = 0; while(m.find()) { //根据规则循环发现字符串 count++; System.out.print("start(): "+m.start()); //被匹配的字符串开始位置 System.out.println("; end(): "+m.end()); //被匹配的字符串结束位置 } System.out.println("Match number "+count); } }
运行结果:
案例2:
import java.util.regex.Matcher; import java.util.regex.Pattern; /** * lookingAt 方法需要从第一字符开始匹配,能匹配返回TRUE。匹配后后面是否还存在字符不关心。 * matches 需要完整匹配,被匹配的字符串不能存在多余字符不能被匹配的情况,才返回TRUE。 */ public class var { private static final String REGEX = "foo"; private static final String INPUT = "fooooooooooooooooo"; private static final String INPUT2 = "ooooofoooooooooooo"; private static Pattern pattern; private static Matcher matcher; private static Matcher matcher2; public static void main(String[] agrs){ pattern = Pattern.compile(REGEX); matcher = pattern.matcher(INPUT); matcher2 = pattern.matcher(INPUT2); System.out.println("Current REGEX is: "+REGEX); System.out.println("Current INPUT is: "+INPUT); System.out.println("Current INPUT2 is: "+INPUT2); System.out.println("lookingAt(): "+matcher.lookingAt()); System.out.println("matches(): "+matcher.matches()); System.out.println("lookingAt(): "+matcher2.lookingAt()); } }
运行结果:
案例3:
/** * replaceAll:将符合规则的字符串替换成另外一个字符串。 * replaceFirst :替换第一个符合规则的。 */ public class var { private static String REGEX = "dog"; private static String INPUT = "The dog says meow. All dogs say meow."; private static String REPLACE = "cat"; public static void main(String[] agrs){ Pattern p = Pattern.compile(REGEX); Matcher m = p.matcher(INPUT); INPUT = m.replaceFirst(REPLACE); System.out.println(INPUT); INPUT = m.replaceAll(REPLACE); System.out.println(INPUT); } }
运行结果:
案例4:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class var { private static String REGEX = "a*b"; private static String INPUT = "aabfooaabfooabfoobkkk"; private static String REPLACE = "-"; public static void main(String[] agrs){ Pattern p = Pattern.compile(REGEX); // 获取 matcher 对象 Matcher m = p.matcher(INPUT); StringBuffer sb = new StringBuffer(); while(m.find()){ m.appendReplacement(sb,REPLACE); //替换字符串INPUT,并且将新字符串写入缓存中sb } m.appendTail(sb); //将剩余字符串在拼接到sb中。 System.out.println(sb.toString()); } }
运行结果:
练习:
匹配邮箱的正则编写。
import java.util.regex.Matcher; import java.util.regex.Pattern; public class var { /** * [0-9]{6,10} :(0-9数据匹配6-10次) * @ 匹配一个@符号 * [A-Za-z0-9]{2,4} 匹配字母,数字匹配2到4次。 * (.com.cn)? 匹配0次或者1次该字符串 */ private static String REGEX = "[0-9]{6,10}@[A-Za-z0-9]{2,4}(.com.cn)?(.com)?"; private static String INPUT = "774834@QQ.com;;hjajshflsdfl;er29953345563344533788988@qq.com.cnhasjkercssdffssd@163.com.cn"; private static String REPLACE = "-"; public static void main(String[] agrs){ Pattern p = Pattern.compile(REGEX); // 获取 matcher 对象 Matcher m = p.matcher(INPUT); while(m.find()){ System.out.println(INPUT.substring(m.start(),m.end())); } } }
运行结果:
参考:https://www.runoob.com/java/java-regular-expressions.html