正则表达式在java中的使用

java.util.regex

java.util.regex 包主要包括以下三个类:

  • Pattern 类:
    pattern对象是一个正则表达式的编译表示。Pattern类没有公共构造方法。要创建一个 Pattern对象,你必须首先调用其公共静态编译方法,它返回一个Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。
  • Matcher 类:
    Matcher对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher也没有公共构造方法。你需要调用 Pattern对象的 matcher 方法来获得一个 Matcher对象。
  • PatternSyntaxException
    PatternSyntaxException是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

Pattern类

创建Pattern

Pattern类用于创建一个正则表达式,也可以说是创建一个匹配模式,可以通过两个静态方法创建:

  • compile(String regex)
  • compile(String regex,int flags)

其中regex是正则表达式,flags为可选模式(如:Pattern.CASE_INSENSITIVE 忽略大小写) 实例:

  1. Pattern pattern = Pattern.compile("Java");
  2. System.out.println(pattern.pattern()); //返回此模式的正则表达式即Java

拆分输入序列

Pattern类还有两个根据匹配模式拆分输入序列的方法:

  • split(CharSequence input)
  • split(CharSequence input, int limit),其中limit为返回元素的个数。 ```java

Pattern pattern = Pattern.compile(“Java”); String test=”123Java456Java789Java”; String[] result = pattern.split(test); for(String s : result){ System.out.println(s); }

// 输出 123 456 789

  1. 细说一下split(CharSequence input int limit),当limit值大于所能返回的字符串的最多个数或者为负数,返回的字符串个数将不受限制,但结尾可能包含空串;当limit=0时与split(CharSequence input)等价,但结尾的空串会被丢弃。
  2. ```java
  3. Pattern pattern = Pattern.compile("Java");
  4. String test = "123Java456Java789Java";
  5. System.out.println("=============limit=2===========");
  6. String[] result = pattern.split(test,2);
  7. System.out.println("result.length:"+result.length);
  8. for(String s : result){
  9. System.out.println(s);
  10. }
  11. System.out.println("=============limit=10===========");
  12. result = pattern.split(test,10);
  13. System.out.println("result.length:"+result.length);
  14. for(String s : result){
  15. System.out.println(s);
  16. }
  17. System.out.println("=============limit=-2===========");
  18. result = pattern.split(test,-2);
  19. System.out.println("result.length:"+result.length);
  20. for(String s : result){
  21. System.out.println(s);
  22. }
  23. System.out.println("=============limit=0===========");
  24. result = pattern.split(test,0);
  25. System.out.println("result.length:"+result.length);
  26. for(String s : result){
  27. System.out.println(s);
  28. }
  29. 输出:
  30. =============limit=2===========
  31. result.length:2
  32. 123
  33. 456Java789Java
  34. =============limit=10===========
  35. result.length:4
  36. 123
  37. 456
  38. 789
  39. =============limit=-2===========
  40. result.length:4
  41. 123
  42. 456
  43. 789
  44. =============limit=0===========
  45. result.length:3
  46. 123
  47. 456
  48. 789
  49. Process finished with exit code 0

判断全字符匹配

Pattern类也自带一个静态匹配方法matches(String regex, CharSequence input),但只能进行全字符串匹配并且只能返回是否匹配上的boolean值
示例:

  1. String test1 = "Java";
  2. String test2 = "Java123456";
  3. System.out.println(Pattern.matches("Java",test1));//返回true
  4. System.out.println(Pattern.matches("Java",test2));//返回false

Matcher对象

获取Matcher

Pattern类中的matcher(CharSequence input)会返回一个Matcher对象。

  1. Pattern pattern = Pattren.complier("java");
  2. String str = "123java456Java789Java";
  3. Matcher matcher = Pattern.matcher(str);

判断匹配字符串

Matcher类提供了三个返回boolean值得匹配方法:

  • matches()
  • lookingAt()
  • find()
  • find(int start)

其中matches()用于全字符串匹配,lookingAt从字符串最开头开始匹配满足的子串,find可以对任意位置字符串匹配,其中start为起始查找索引值。

  1. Pattern pattern = Pattern.compile("Java");
  2. String test1 = "Java";
  3. String test2 = "Java1234";
  4. String test3 = "1234Java"
  5. Matcher matcher = pattern.matcher(test1);
  6. System.out.println(matcher.matches());//返回true
  7. matcher = pattern.matcher(test2);
  8. System.out.println(matcher.matches());//返回false
  9. matcher = pattern.matcher(test2);
  10. System.out.println(matcher.lookingAt())://返回true
  11. matcher = pattern.matcher(test3);
  12. System.out.println(matcher.lookingAt());//返回false
  13. matcher = pattern.matcher(test1);
  14. System.out.println(matcher.find());//返回true
  15. matcher = pattern.matcher(test2);
  16. System.out.println(matcher.find());//返回true
  17. matcher = pattern.matcher(test3);
  18. System.out.println(matcher.find(2));//返回true
  19. matcher = pattern.matcher(test3);
  20. System.out.println(matcher.find(5));//返回false

返回匹配值

Matcher类提供了start(),end(),group()分别用于返回字符串的起始索引,结束索引,以及匹配到到的字符串。
实例:

  1. Pattern pattern = Pattern.compile("Java");
  2. String test = "123Java456";
  3. Matcher matcher = pattern.matcher(test);
  4. matcher.find();
  5. System.out.println(matcher.start());//返回3
  6. System.out.println(matcher.end());//返回7
  7. System.out.println(matcher.group());//返回Java

分组操作

组的概念:组是用括号划分的正则表达式,可以根据组的编号来引用这个组。组号为0表示整个表达式,组号为1表示被第一对括号括起的组,依次类推。

例如 A(B(C))D,组0是ABCD,组1是BC,组2是C。

Matcher类提供了start(int group),end(int group),group(int i),groupCount()用于分组操作。

  • start(int group) // 返回指定组对应的开始索引
  • end(int group) // 返回指定组对应的结束索引
  • String group(int i) // 返回第i组匹配到的字符串
  • int groupCount() // 组数量

Matcher类提供了start(int gropu),end(int group),group(int i),groupCount()用于分组操作
示例:

  1. Pattern pattern = Pattern.compile("(Java)(Python)");
  2. String test = "123JavaPython456";
  3. Matcher matcher = pattern.matcher(test);
  4. matcher.find();
  5. System.out.println(matcher.groupCount());//返回2
  6. System.out.println(matcher.group(1));//返回第一组匹配到的字符串"Java",注意起始索引是1
  7. System.out.println(matcher.start(1));//返回3,第一组起始索引
  8. System.out.println(matcher.end(1));//返回7 第一组结束索引
  9. System.out.println(matcher.group(2));//返回第二组匹配到的字符串"Python"
  10. System.out.println(matcher.start(2));//返回7,第二组起始索引
  11. System.out.println(matcher.end(2));//返回13 第二组结束索引

设置查找范围

Matcher类还提供region(int start, int end)(不包括end)方法用于设定查找范围,并提供regionStrat()和regionEnd()用于返回起始和结束查找的索引

  1. Pattern pattern = Pattern.compile("Java");
  2. String test = "123JavaJava";
  3. Matcher matcher = pattern.matcher(test);
  4. matcher.region(7, 11);
  5. System.out.println(matcher.regionStart());//返回7
  6. System.out.println(matcher.regionEnd());//返回11
  7. matcher.find();
  8. System.out.println(matcher.group());//返回Java

重置匹配器

Matcher类提供了两种用于重置当前匹配器的方法:reset()和reset(CharSequence input)

  1. Pattern pattern = Pattern.compile("Java");
  2. String test = "Java";
  3. Matcher matcher = pattern.matcher(test);
  4. matcher.find();
  5. System.out.println(matcher.group());//返回Java
  6. matcher.reset();//从起始位置重新匹配
  7. matcher.find();
  8. System.out.println(matcher.group());//返回Java
  9. matcher.reset("Python");
  10. System.out.println(matcher.find());//返回false

匹配替换字符串

Matcher 类同时提供了四个将匹配子串替换成指定字符串的方法:

  • replaceAll(String replacement)
  • replaceFirst(String replacement)
  • appendReplacement(StringBuffer sb, String replacement)
  • appendTail(StringBuffer sb)

其中replaceAll是替换全部匹配到的字符串,而replaceFirst仅仅是替换第一个匹配到的字符串。

  1. Pattern pattern = Pattern.compile("Java");
  2. String test = "JavaJava";
  3. Matcher matcher = pattern.matcher(test);
  4. System.out.println(matcher.replaceAll("Python"));//返回PythonPython
  5. System.out.println(matcher.replaceFirst("python"));//返回PythonJava

appendReplacement(StringBuffer sb, String replacement) 将当前匹配子串替换为指定字符串,并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个StringBuffer对象里。appendTail(StringBuffer sb) 将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。
示例:

  1. package com.dajiangtai.djt_spider.util;
  2. import java.util.regex.Matcher;import java.util.regex.Pattern;
  3. public class MatcherTest {
  4. public static void main(String[] args)throws Exception {
  5. //生成Pattern对象并且编译一个简单的正则表达式"Kelvin"
  6. Pattern p = Pattern.compile("Kelvin");
  7. //用Pattern类的matcher()方法生成一个Matcher对象
  8. Matcher m = p.matcher("Kelvin Li and Kelvin Chan are both working in Kelvin Chen's KelvinSoftShop company");
  9. StringBuffer sb = new StringBuffer();
  10. int i=0;
  11. //使用find()方法查找第一个匹配的对象
  12. boolean result = m.find();
  13. //使用循环将句子里所有的kelvin找出并替换再将内容加到sb里
  14. while(result) {
  15. i++;
  16. m.appendReplacement(sb, "Kevin");
  17. System.out.println("第"+i+"次匹配后sb的内容是:"+sb);
  18. //继续查找下一个匹配对象
  19. result = m.find();
  20. }
  21. //最后调用appendTail()方法将最后一次匹配后的剩余字符串加到sb里;
  22. m.appendTail(sb);
  23. System.out.println("调用m.appendTail(sb)后sb的最终内容是:"+ sb.toString());
  24. }
  25. }
  26. 输出:
  27. 1次匹配后sb的内容是:Kevin
  28. 2次匹配后sb的内容是:Kevin Li and Kevin
  29. 3次匹配后sb的内容是:Kevin Li and Kevin Chan are both working in Kevin
  30. 4次匹配后sb的内容是:Kevin Li and Kevin Chan are both working in Kevin Chen's Kevin
  31. 调用m.appendTail(sb)后sb的最终内容是:Kevin Li and Kevin Chan are both working in Kevin Chen's KevinSoftShop company

例如,有字符串fatcatfatcatfat,假设既有正则表达式模式为”cat”,第一次匹配后调用appendReplacement(sb,”dog”),那么这时StringBuffer sb的内容为fatdog,也就是fatcat中的cat被替换为dog并且与匹配子串前的内容加到sb里,而第二次匹配后调用appendReplacement(sb,”dog”),那么sb的内容就变为fatdogfatdog,如果最后再调用一次appendTail(sb),那么sb最终的内容将是fatdogfatdogfat。