正则表达式工具类 - RegexUtil

1.前言

在文本处理中,正则表达式几乎是全能的,但Java的正则表达式有时候处理写起来比较繁琐,所以该工具类封装了部分常用功能,以简化代码书写。就如说我要匹配一段文本中的某些部分,我们需要这样做:

  1. import java.util.regex.Matcher;
  2. import java.util.regex.Pattern;
  3. ...
  4. Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
  5. Matcher matcher = pattern.matcher(content);
  6. if (matcher.find()) {
  7. String result= matcher.group();
  8. }

其中牵涉到多个对象,用的时候不太容易记住,而且写起来也繁杂。因此,此处做了一层封装,简化调用:

  1. /**
  2. * 编译给定正则表达式 <code>regexPattern</code> 并尝试将给定输入 <code>input</code> 与其匹配.
  3. *
  4. * <p>
  5. * {@link Pattern#matches(String, CharSequence)} 等价于{@link #getMatcher(String, CharSequence)}.matches();
  6. * </p>
  7. *
  8. * @param regexPattern
  9. * 正则表达式字符串,pls use {@link RegexPattern}
  10. * @param input
  11. * The character sequence to be matched,support {@link String},{@link StringBuffer},{@link StringBuilder}... and so on
  12. * @return 如果input 符合 regex的正则表达式格式,返回true, 否则返回 false;<br>
  13. * 如果 <code>regexPattern</code> 是null,抛出 {@link NullPointerException}<br>
  14. * 如果 <code>input</code> 是null,抛出 {@link NullPointerException}<br>
  15. * @see #getMatcher(String, CharSequence)
  16. * @see Matcher#matches()
  17. * @see Pattern#matches(String, CharSequence)
  18. * @since 1.0.7
  19. */
  20. public static boolean matches(String regexPattern,CharSequence input){
  21. return getMatcher(regexPattern, input).matches();
  22. }
  23. /**
  24. * 返回在以前匹配操作期间由给定组捕获的输入子序列.
  25. *
  26. * <p>
  27. * 对于匹配器 m、输入序列 s 和组索引 g,表达式 m.group(g) 和 s.substring(m.start(g), m.end(g))是等效的.<br>
  28. * 捕获组是从 1开始从左到右的索引.组0表示整个模式,因此表达式 m.group(0)等效于 m.group().
  29. * </p>
  30. *
  31. * <h3>示例:</h3>
  32. *
  33. * <blockquote>
  34. *
  35. * <pre class="code">
  36. * String regexPattern = "(.*?)@(.*?)";
  37. * String email = "venusdrogon@163.com";
  38. * RegexUtil.group(regexPattern, email);
  39. * </pre>
  40. *
  41. * <b>返回:</b>
  42. *
  43. * <pre class="code">
  44. * 0 venusdrogon@163.com
  45. * 1 venusdrogon
  46. * 2 163.com
  47. * </pre>
  48. *
  49. * </blockquote>
  50. *
  51. * @param regexPattern
  52. * 正则表达式字符串,pls use {@link RegexPattern}
  53. * @param input
  54. * The character sequence to be matched,support {@link String},{@link StringBuffer},{@link StringBuilder}... and so on
  55. * @return 如果 <code>regexPattern</code> 是null,抛出 {@link NullPointerException}<br>
  56. * 如果 <code>input</code> 是null,抛出 {@link NullPointerException}<br>
  57. * 如果 匹配不了,返回 {@link java.util.Collections#emptyMap()}
  58. * @see #getMatcher(String, CharSequence)
  59. * @see Matcher#group(int)
  60. * @since 1.0.7
  61. */
  62. public static Map<Integer, String> group(String regexPattern,CharSequence input){
  63. Matcher matcher = getMatcher(regexPattern, input);
  64. if (!matcher.matches()){
  65. LOGGER.trace("[not matches] ,\n\tregexPattern:[{}] \n\tinput:[{}]", regexPattern, input);
  66. return emptyMap();
  67. }
  68. int groupCount = matcher.groupCount();
  69. Map<Integer, String> map = newLinkedHashMap(groupCount + 1);
  70. for (int i = 0; i <= groupCount; ++i){
  71. //匹配的索引
  72. String groupValue = matcher.group(i); //map.put(0, matcher.group());// 捕获组是从 1 开始从左到右的索引.组0表示整个模式,因此表达式 m.group(0) 等效于 m.group().
  73. LOGGER.trace("matcher group[{}],start-end:[{}-{}],groupValue:[{}]", i, matcher.start(i), matcher.end(i), groupValue);
  74. map.put(i, groupValue);//groupValue
  75. }
  76. if (LOGGER.isTraceEnabled()){
  77. LOGGER.trace("regexPattern:[{}],input:[{}],groupMap:{}", regexPattern, input, JsonUtil.format(map));
  78. }
  79. return map;
  80. }
  81. /**
  82. * 返回在以前匹配操作期间由给定组捕获的输入子序列.
  83. *
  84. * <p>
  85. * 对于匹配器 m、输入序列 s 和组索引 g,表达式 m.group(g) 和 s.substring(m.start(g), m.end(g))是等效的.<br>
  86. * 捕获组是从 1开始从左到右的索引.组0表示整个模式,因此表达式 m.group(0)等效于 m.group().
  87. * </p>
  88. *
  89. * <h3>示例:</h3>
  90. *
  91. * <blockquote>
  92. *
  93. * <pre class="code">
  94. *
  95. * String regexPattern = "(.*?)@(.*?)";
  96. * String email = "venusdrogon@163.com";
  97. * LOGGER.info(RegexUtil.group(regexPattern, email, 1) + "");//venusdrogon
  98. * LOGGER.info(RegexUtil.group(regexPattern, email, 2) + "");//163.com
  99. *
  100. * </pre>
  101. *
  102. * </blockquote>
  103. *
  104. * @param regexPattern
  105. * 正则表达式字符串,pls use {@link RegexPattern}
  106. * @param input
  107. * The character sequence to be matched,support {@link String},{@link StringBuffer},{@link StringBuilder}... and so on
  108. * @param group
  109. * the group
  110. * @return 如果 <code>regexPattern</code> 是null,抛出 {@link NullPointerException}<br>
  111. * 如果 <code>input</code> 是null,抛出 {@link NullPointerException}<br>
  112. * @see #getMatcher(String, CharSequence)
  113. * @see Matcher#group(int)
  114. * @since 1.0.7
  115. */
  116. public static String group(String regexPattern,CharSequence input,int group){
  117. Map<Integer, String> map = group(regexPattern, input);
  118. return map.get(group);
  119. }

2.RegexUtil.matches(String, CharSequence)方法

我们常用来做 字符串 匹配正则表达式校验

比如 测试手机号码的单元测试类 https://github.com/venusdrogon/feilong-core/blob/master/src/test/java/com/feilong/core/util/regexutiltest/MobilephonePatternParameterizedTest.java

  1. @Parameters(name = "RegexUtil.matches(RegexPattern.MOBILEPHONE, {0})={1}")
  2. public static Iterable<Object[]> data(){
  3. String[] valids = { "18501646315", "15001841317", "14701841318" };
  4. String[] invalids = { //
  5. "",
  6. " ",
  7. "1500184131", // count not match
  8. " 18501646315", // count not match
  9. "18501646315 ", // count not match
  10. "10201841318", //no 10
  11. "11201841318", //no 11
  12. "12201841318", //no 12
  13. "16201841318", //no 16
  14. "19201841318" //no 19
  15. };
  16. return TestUtil.toDataList(valids, invalids);
  17. }
  18. /**
  19. * Matches.
  20. */
  21. @Test
  22. public void matches(){
  23. assertEquals(expectedValue, RegexUtil.matches(MOBILEPHONE, input));
  24. }

3.RegexUtil.group(String, CharSequence)方法

返回在以前匹配操作期间由给定组捕获的输入子序列.

对于匹配器 m、输入序列 s 和组索引 g,表达式 m.group(g)s.substring(m.start(g), m.end(g))是等效的.捕获组是从 1开始从左到右的索引.组0表示整个模式,因此表达式 m.group(0)等效于 m.group().

示例:

  1. String regexPattern = "(.*?)@(.*?)";
  2. String email = "venusdrogon@163.com";
  3. RegexUtil.group(regexPattern, email);

返回:

  1. 0 venusdrogon@163.com
  2. 1 venusdrogon
  3. 2 163.com