请选择 进入手机版 | 继续访问电脑版

[java] Java Pattern与Matcher字符串匹配案例详解

[复制链接]
查看38 | 回复6 | 2021-9-13 02:36:42 | 显示全部楼层 |阅读模式

Pattern类定义

         public final class Pattern extends Object implementsSerializable正则表达式的编译表示情势 。用于编译正则表达式后创建一个匹配模式。

        指定为字符串的正则表达式必须起首 被编译为此类的实例。然后,可将得到的模式用于创建Matcher对象,依照正则表达式,该对象可以与恣意 字符序列匹配。实行 匹配所涉及的全部 状态都驻留在匹配器中,以是 多个匹配器可以共享同一模式。

        因此,典型的调用次序 是:

  1. Pattern p =Pattern.compile("a*b");
  2. Matcher m =p.matcher("aaaaab");
  3. boolean b = m.matches();
复制代码

        在仅使用 一次正则表达式时,可以方便地通过此类定义matches方法。此方法编译表达式并在单个调用中将输入序列与其匹配。语句:

  1. boolean b =Pattern.matches("a*b", "aaaaab");
复制代码

        等效于上面的三个语句,只管 对于重复的匹配而言它服从 不高,由于 它不答应 重用已编译的模式。

        此类的实例是不可变的,可供多个并发线程安全使用 。Matcher类的实例用于此目的 则不安全。

Pattern类方法详解

        1、Pattern complie(String regex):编译正则表达式,并创建Pattern类。

        由于Pattern的构造函数是私有的,不可以直接创建,以是 通过静态的简单工厂方法compile(String regex)方法来创建,将给定的正则表达式编译并赋予给Pattern类。

        2、String pattern():返回正则表达式的字符串情势 。

        实在 就是返回Pattern.complile(Stringregex)的regex参数。示比方 下:

  1. String regex ="\\?|\\*";
  2. Pattern pattern= Pattern.compile(regex);
  3. StringpatternStr = pattern.pattern();//返回\?\*
复制代码

        3、Pattern compile(String regex, int flags)。

        方法功能和compile(Stringregex)雷同 ,不过增长 了flag参数,flag参数用来控制正则表达式的匹配活动 ,可取值范围如下:

        Pattern.CANON_EQ:启用规范等价。当且仅当两个字符的“正规分解(canonicaldecomposition)”都完全雷同 的环境 下,才认定匹配。默认环境 下,不思量 “规范相当 性(canonical equivalence)”。

        Pattern.CASE_INSENSITIVE:启用不区分大小写的匹配。默认环境 下,大小写不敏感的匹配只实用 于US-ASCII字符集。这个标志能让表达式忽略大小写举行 匹配,要想对Unicode字符举行 大小不敏感的匹配,只要将UNICODE_CASE与这个标志合起来就行了。

        Pattern.COMMENTS:模式中答应 空缺 和表明 。在这种模式下,匹配时会忽略(正则表达式里的)空格字符(不是指表达式里的“\s”,而是指表达式里的空格,tab,回车之类)。表明 从#开始,不停 到这行竣事 。可以通过嵌入式的标志来启用Unix行模式。

        Pattern.DOTALL:启用dotall模式。在这种模式下,表达式‘.'可以匹配恣意 字符,包括表示一行的竣事 符。默认环境 下,表达式‘.'不匹配行的竣事 符。

        Pattern.LITERAL:启用模式的字面值剖析 。

        Pattern.MULTILINE:启用多行模式。在这种模式下,‘\^'和‘$'分别匹配一行的开始和竣事 。此外,‘^'仍旧 匹配字符串的开始,‘$'也匹配字符串的竣事 。默认环境 下,这两个表达式仅仅匹配字符串的开始和竣事 。

        Pattern.UNICODE_CASE:启用Unicode感知的大小写折叠。在这个模式下,假如 你还启用了CASE_INSENSITIVE标志,那么它会对Unicode字符举行 大小写不敏感的匹配。默认环境 下,大小写不敏感的匹配只实用 于US-ASCII字符集。

        Pattern.UNIX_LINES:  启用Unix行模式。在这个模式下,只有‘\n'才被认作一行的中断 ,并且与‘.'、‘^'、以及‘$'举行 匹配。

        4、int flags():返回当前Pattern的匹配flag参数。

        5、String[] split(CharSequence input)。

        Pattern有一个split(CharSequenceinput)方法,用于分隔字符串,并返回一个String[]。此外String[] split(CharSequence input, int limit)功能和String[]split(CharSequence input)雷同 ,增长 参数limit目的 在于要指定分割的段数。

        6、static boolean matches(String regex, CharSequenceinput)。

        是一个静态方法,用于快速匹配字符串,该方法得当 用于只匹配一次,且匹配全部字符串。方法编译给定的正则表达式并且对输入的字串以该正则表达式为模式开展匹配,该方法只举行 一次匹配工作,并不必要 天生 一个Matcher实例。

        7、Matcher matcher(CharSequence input)。

        Pattern.matcher(CharSequenceinput)返回一个Matcher对象。Matcher类的构造方法也是私有的,不能随意创建,只能通过Pattern.matcher(CharSequence input)方法得到该类的实例。Pattern类只能做一些简单的匹配操作,要想得到更强更便捷的正则匹配操作,那就必要 将Pattern与Matcher一起合作。Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持。

        Java代码示例:

  1. Pattern p = Pattern.compile("\\d+");
  2. Matcher m = p.matcher("22bb23");
  3. // 返回p也就是返回该Matcher对象是由哪个Pattern对象的创建的
  4. m.pattern();
复制代码

Pattern类使用 示例:

  1. package com.zxt.regex;
  2. import java.util.regex.Pattern;
  3. public classPatternTest {
  4. public static void main(String[] args) {
  5. // 使用Pattern.compile方法编译一个正则表达式,创建一个匹配模式
  6. Patternpattern = Pattern.compile("\\?|\\*");
  7. // pattern()函数返回正则表达式的字符串形式返回\?\*
  8. StringpatternStr = pattern.pattern();
  9. System.out.println(patternStr);
  10. // flags()返回当前Pattern的匹配flag参数,这里并没有定义
  11. int flag = pattern.flags();
  12. System.out.println(flag);
  13. // split方法对字符串进行分割
  14. // 123 123 456 456
  15. String[]splitStrs = pattern.split("123?123*456*456");
  16. for (int i = 0; i < splitStrs.length; i++) {
  17. System.out.print(splitStrs[i] + " ");
  18. }
  19. System.out.println();
  20. // 123 123*456*456
  21. String[]splitStrs2 = pattern.split("123?123*456*456",2);
  22. for (int i = 0; i < splitStrs2.length; i++) {
  23. System.out.print(splitStrs2[i] + " ");
  24. }
  25. System.out.println();
  26. Patternp = Pattern.compile("\\d+");
  27. String[]str = p.split("我的QQ是:456456我的电话是:0532214我的邮箱是:aaa@aaa.com");
  28. for (int i = 0; i < str.length; i++) {
  29. System.out.printf("str[%d] = %s\n",i, str[i]);
  30. }
  31. System.out.println();
  32. // Pattern.matches用给定的模式对字符串进行一次匹配,(需要全匹配时才返回true)
  33. System.out.println("Pattern.matches("\\\\d+","2223") is " + Pattern.matches("\\d+", "2223"));
  34. // 返回false,需要匹配到所有字符串才能返回true,这里aa不能匹配到
  35. System.out.println("Pattern.matches("\\\\d+", "2223aa")is " + Pattern.matches("\\d+", "2223aa"));
  36. // 返回false,需要匹配到所有字符串才能返回true,这里bb不能匹配到
  37. System.out.println("Pattern.matches("\\\\d+","22bb23") is " + Pattern.matches("\\d+", "22bb23"));
  38. }
  39. }
复制代码

Java Pattern与Matcher字符串匹配案例详解

Matcher类定义

        public final class Matcher extends Object implementsMatchResult通过调用模式(Pattern)的matcher方法从模式创建匹配器。创建匹配器后,可以使用 它实行 三种不同的匹配操作:

        1、matches方法尝试将整个输入序列与该模式匹配。

        2、lookingAt尝试将输入序列从头开始与该模式匹配。

        3、find方法扫描输入序列以查找与该模式匹配的下一个子序列。

        每个方法都返回一个表示成功或失败的布尔值。通过查询匹配器的状态可以获取关于成功匹配的更多信息。

        匹配器在其输入的子集(称为地区 )中查找匹配项。默认环境 下,此地区 包含全部的匹配器输入。可通过region方法修改地区 ,通过regionStart和regionEnd方法查询地区 。地区 边界与某些模式构造交互的方式是可以更改的。

        此类还定义使用 新字符串更换 匹配子序列的方法,必要 时,可以从匹配结果 计算出新字符串的内容。可以先后使用 appendReplacement和appendTail方法将结果 网络 到现有的字符串缓冲区,或者使用 更加便捷的replaceAll方法创建一个可以在此中 更换 输入序列中每个匹配子序列的字符串。

        匹配器的显式状态包括迩来 成功匹配的开始和竣事 索引。它还包括模式中每个捕获组捕获的输入子序列的开始和竣事 索引以及该子序列的总数。出于方便的思量 ,还提供了以字符串的情势 返回这些已捕获子序列的方法。

        匹配器的显式状态最初是未定义的;在成功匹配导致IllegalStateException抛出之前尝试查询此中 的任何部分。每个匹配操作都将重新计算匹配器的显式状态。匹配器的隐式状态包括输入字符序列和添加位置,添加位置最初是零,然后由appendReplacement方法更新。

        可以通过调用匹配器的reset()方法来显式重置匹配器,假如 必要 新输入序列,则调用其reset(CharSequence)方法。重置匹配器将放弃其显式状态信息并将添加位置设置为零。

        此类的实例用于多个并发线程是不安全的。

Matcher类方法详解

        1、Matcher类提供了三个匹配操作方法,三个方法均返回boolean范例 ,当匹配到时返回true,没匹配到则返回false。

        boolean matches()最常用方法:尝试对整个目的 字符睁开 匹配检测,也就是只有整个目的 字符串完全匹配时才返回真值。

        boolean lookingAt()对前面的字符串举行 匹配,只有匹配到的字符串在最前面才会返回true。

        boolean find():对字符串举行 匹配,匹配到的字符串可以在任何位置。

        2、返回匹配器的表现 状态:intstart():返回当前匹配到的字符串在原目的 字符串中的位置;int end():返回当前匹配的字符串的末了 一个字符在原目的 字符串中的索引位置;String group():返回匹配到的子字符串。

        3、int start(),int end(),int group()均有一个重载方法,它们分别是int start(int i),int end(int i),int group(int i)专用于分组操作,Mathcer类还有一个groupCount()用于返回有多少组。

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

        1)、String replaceAll(Stringreplacement):将目的 字符串里与既有模式相匹配的子串全部更换 为指定的字符串。

        2)、String replaceFirst(Stringreplacement):将目的 字符串里第一个与既有模式相匹配的子串更换 为指定的字符串。

        3)、还有两个方法Matcher appendReplacement(StringBuffersb, String replacement) 和StringBufferappendTail(StringBuffer sb)也很紧张 ,appendReplacement答应 直接将匹配的字符串保存在另一个StringBuffer中并且是渐进式匹配,并不是只匹配一次或匹配全部,而appendTail则是将未匹配到的余下的字符串添加到StringBuffer中。

        5、其他一些方法:比方 Matcherreset():重设该Matcher对象。

        Matcher reset(CharSequence input):重设该Matcher对象并且指定一个新的目的 字符串。

        Matcher region(int start, int end):设置此匹配器的地区 限定 。

Matcher类使用 示例:

  1. package com.zxt.regex;
  2. import java.util.regex.Matcher;
  3. import java.util.regex.Pattern;
  4. public classMatcherTest {
  5. public static void main(String[] args) {
  6. Patternp = Pattern.compile("\\d+");
  7. // matches()对整个字符串进行匹配
  8. // 返回false,因为bb不能被\d+匹配,导致整个字符串匹配未成功。
  9. Matcherm = p.matcher("22bb23");
  10. System.out.println(m.matches());
  11. m = p.matcher("2223");
  12. // 返回true,因为\d+匹配到了整个字符串
  13. System.out.println(m.matches());
  14. // lookingAt()对字符串前缀进行匹配
  15. m = p.matcher("22bb23");
  16. // 返回true,因为\d+匹配到了前面的22
  17. System.out.println(m.lookingAt());
  18. m = p.matcher("aa2223");
  19. // 返回false,因为\d+不能匹配前面的aa
  20. System.out.println(m.lookingAt());
  21. // find()对字符串进行匹配,匹配到的字符串可以在任何位置。
  22. m = p.matcher("22bb23");
  23. System.out.println(m.find()); // true
  24. m = p.matcher("aa2223");
  25. System.out.println(m.find()); // true
  26. m = p.matcher("aabb");
  27. System.out.println(m.find()); // false
  28. // 当匹配器匹配失败时,使用返回匹配器状态的方法将出错,例如:m.start();
  29. m = p.matcher("aa2223bb");
  30. System.out.println(m.find()); // true
  31. System.out.println(m.start()); // 2
  32. System.out.println(m.end()); // 6
  33. System.out.println(m.group()); // 2223
  34. p = Pattern.compile("([a-z]+)(\\d+)");
  35. m = p.matcher("aaa2223bb");
  36. // 匹配aaa2223
  37. m.find();
  38. // 返回2,因为有2组
  39. System.out.println(m.groupCount());
  40. // 返回0, 返回第一组匹配到的子字符串在字符串中的索引号
  41. System.out.println(m.start(1));
  42. // 返回3
  43. System.out.println(m.start(2));
  44. // 返回3 返回第一组匹配到的子字符串的最后一个字符在字符串中的索引位置.
  45. System.out.println(m.end(1));
  46. // 返回2223,返回第二组匹配到的子字符串
  47. System.out.println(m.group(2));
  48. }
  49. }
复制代码

应用实例

1、一个简单的邮箱验证小程序

  1. package com.zxt.regex;
  2. import java.util.Scanner;
  3. import java.util.regex.Matcher;
  4. import java.util.regex.Pattern;
  5. /*
  6. * 一个简单的邮件地址匹配程序
  7. */
  8. public classEmailMatch {
  9. public static void main(String[] args) throws Exception {
  10. Scannersc = new Scanner(System.in);
  11. while (sc.hasNext()) {
  12. Stringinput = sc.nextLine();
  13. // 检测输入的EMAIL地址是否以非法符号"."或"@"作为起始字符
  14. Patternp = Pattern.compile("^@");
  15. Matcherm = p.matcher(input);
  16. if (m.lookingAt()) {
  17. System.out.println("EMAIL地址不能以'@'作为起始字符");
  18. }
  19. // 检测是否以"www."为起始
  20. p = Pattern.compile("^www.");
  21. m = p.matcher(input);
  22. if (m.lookingAt()) {
  23. System.out.println("EMAIL地址不能以'www.'起始");
  24. }
  25. // 检测是否包含非法字符
  26. p = Pattern.compile("[^A-Za-z0-9.@_-~#]+");
  27. m = p.matcher(input);
  28. StringBuffersb = new StringBuffer();
  29. boolean result = m.find();
  30. boolean deletedIllegalChars= false;
  31. while (result) {
  32. // 如果找到了非法字符那么就设下标记
  33. deletedIllegalChars= true;
  34. // 如果里面包含非法字符如冒号双引号等,那么就把他们消去,加到SB里面
  35. m.appendReplacement(sb, "");
  36. result = m.find();
  37. }
  38. // 此方法从添加位置开始从输入序列读取字符,并将其添加到给定字符串缓冲区。
  39. // 可以在一次或多次调用 appendReplacement 方法后调用它来复制剩余的输入序列。
  40. m.appendTail(sb);
  41. if (deletedIllegalChars){
  42. System.out.println("输入的EMAIL地址里包含有冒号、逗号等非法字符,请修改");
  43. System.out.println("您现在的输入为: " + input);
  44. System.out.println("修改后合法的地址应类似: " + sb.toString());
  45. }
  46. }
  47. sc.close();
  48. }
  49. }
复制代码

Java Pattern与Matcher字符串匹配案例详解

2、判定 身份证:要么是15位,要么是18位,末了 一位可以为字母,并写程序提出此中 的年代 日。

        可以使用 正则表达式来定义复杂的字符串格式:(\d{17}[0-9a-zA-Z]|\d{14}[0-9a-zA-Z])可以用来判定 是否为合法的15位或18位身份证号码。由于 15位和18位的身份证号码都是从7位到第12位为身份证为日期范例 。如许 我们可以计划 出更正确 的正则模式,提取身份证号中的日期信息。

  1. package com.zxt.regex;
  2. import java.util.regex.Matcher;
  3. import java.util.regex.Pattern;
  4. public classIdentityMatch {
  5. public static void main(String[] args) {
  6. // 测试是否为合法的身份证号码
  7. String[]id_cards = { "130681198712092019","13068119871209201x","13068119871209201","123456789012345",
  8. "12345678901234x","1234567890123"};
  9. // 测试是否为合法身份证的正则表达式
  10. Patternpattern = Pattern.compile("(\\d{17}[0-9a-zA-Z]|\\d{14}[0-9a-zA-Z])");
  11. // 用于提取出生日字符串的正则表达式
  12. Patternpattern1 = Pattern.compile("\\d{6}(\\d{8}).*");
  13. // 用于将生日字符串分解为年月日的正则表达式
  14. Patternpattern2 = Pattern.compile("(\\d{4})(\\d{2})(\\d{2})");
  15. Matchermatcher = pattern.matcher("");
  16. for (int i = 0; i < id_cards.length; i++) {
  17. matcher.reset(id_cards[i]);
  18. System.out.println(id_cards[i] + " is id cards:" + matcher.matches());
  19. // 如果它是一个合法的身份证号,提取出出生的年月日
  20. if (matcher.matches()) {
  21. Matchermatcher1 = pattern1.matcher(id_cards[i]);
  22. matcher1.lookingAt();
  23. Stringbirthday = matcher1.group(1);
  24. Matchermatcher2 = pattern2.matcher(birthday);
  25. if (matcher2.find()) {
  26. System.out.println("它对应的出生年月日为:" + matcher2.group(1) + "年" + matcher2.group(2) + "月"
  27. +matcher2.group(3) + "日");
  28. }
  29. }
  30. System.out.println();
  31. }
  32. }
  33. }
复制代码

Java Pattern与Matcher字符串匹配案例详解

到此这篇关于Java Pattern与Matcher字符串匹配案例详解的文章就先容 到这了,更多干系 Java Pattern与Matcher字符串匹配内容请搜刮 脚本之家从前 的文章或继续欣赏 下面的干系 文章盼望 大家以后多多支持脚本之家!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

avatar 秦基兴拍 | 2021-9-27 08:33:11 | 显示全部楼层
admin楼主,我告诉你一个你不知道的的秘密,有一个牛逼的源码论坛他的站点都是商业源码,还是免费下载的那种!特别好用。访问地址:http://www.mxswl.com 猫先森网络
回复

使用道具 举报

avatar 强绝商爸摇 | 2021-9-28 08:26:09 | 显示全部楼层
admin楼主看起来很有学问!
回复

使用道具 举报

avatar 风男人1984 | 2021-10-5 04:18:54 | 显示全部楼层
论坛人气好旺!
回复

使用道具 举报

avatar 萍381 | 2021-10-5 11:10:35 | 显示全部楼层
终于看完了,很不错!
回复

使用道具 举报

admin楼主加油,看好你哦!
回复

使用道具 举报

avatar 刺客325 | 前天 11:42 | 显示全部楼层
admin楼主,您提前出院了?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则