正则表达式工具类 - RegexUtil ## 1.前言 在文本处理中,`正则表达式`几乎是全能的,但Java的正则表达式有时候处理写起来比较繁琐,所以该工具类封装了部分常用功能,以简化代码书写。就如说我要匹配一段文本中的某些部分,我们需要这样做: ```JAVA import java.util.regex.Matcher; import java.util.regex.Pattern; ... Pattern pattern = Pattern.compile(regex, Pattern.DOTALL); Matcher matcher = pattern.matcher(content); if (matcher.find()) { String result= matcher.group(); } ``` 其中牵涉到多个对象,用的时候不太容易记住,而且写起来也繁杂。 因此,此处做了一层封装,简化调用: ```JAVA /** * 编译给定正则表达式 <code>regexPattern</code> 并尝试将给定输入 <code>input</code> 与其匹配. * * <p> * {@link Pattern#matches(String, CharSequence)} 等价于{@link #getMatcher(String, CharSequence)}.matches(); * </p> * * @param regexPattern * 正则表达式字符串,pls use {@link RegexPattern} * @param input * The character sequence to be matched,support {@link String},{@link StringBuffer},{@link StringBuilder}... and so on * @return 如果input 符合 regex的正则表达式格式,返回true, 否则返回 false;<br> * 如果 <code>regexPattern</code> 是null,抛出 {@link NullPointerException}<br> * 如果 <code>input</code> 是null,抛出 {@link NullPointerException}<br> * @see #getMatcher(String, CharSequence) * @see Matcher#matches() * @see Pattern#matches(String, CharSequence) * @since 1.0.7 */ public static boolean matches(String regexPattern,CharSequence input){ return getMatcher(regexPattern, input).matches(); } /** * 返回在以前匹配操作期间由给定组捕获的输入子序列. * * <p> * 对于匹配器 m、输入序列 s 和组索引 g,表达式 m.group(g) 和 s.substring(m.start(g), m.end(g))是等效的.<br> * 捕获组是从 1开始从左到右的索引.组0表示整个模式,因此表达式 m.group(0)等效于 m.group(). * </p> * * <h3>示例:</h3> * * <blockquote> * * <pre class="code"> * String regexPattern = "(.*?)@(.*?)"; * String email = "venusdrogon@163.com"; * RegexUtil.group(regexPattern, email); * </pre> * * <b>返回:</b> * * <pre class="code"> * 0 venusdrogon@163.com * 1 venusdrogon * 2 163.com * </pre> * * </blockquote> * * @param regexPattern * 正则表达式字符串,pls use {@link RegexPattern} * @param input * The character sequence to be matched,support {@link String},{@link StringBuffer},{@link StringBuilder}... and so on * @return 如果 <code>regexPattern</code> 是null,抛出 {@link NullPointerException}<br> * 如果 <code>input</code> 是null,抛出 {@link NullPointerException}<br> * 如果 匹配不了,返回 {@link java.util.Collections#emptyMap()} * @see #getMatcher(String, CharSequence) * @see Matcher#group(int) * @since 1.0.7 */ public static Map<Integer, String> group(String regexPattern,CharSequence input){ Matcher matcher = getMatcher(regexPattern, input); if (!matcher.matches()){ LOGGER.trace("[not matches] ,\n\tregexPattern:[{}] \n\tinput:[{}]", regexPattern, input); return emptyMap(); } int groupCount = matcher.groupCount(); Map<Integer, String> map = newLinkedHashMap(groupCount + 1); for (int i = 0; i <= groupCount; ++i){ //匹配的索引 String groupValue = matcher.group(i); //map.put(0, matcher.group());// 捕获组是从 1 开始从左到右的索引.组0表示整个模式,因此表达式 m.group(0) 等效于 m.group(). LOGGER.trace("matcher group[{}],start-end:[{}-{}],groupValue:[{}]", i, matcher.start(i), matcher.end(i), groupValue); map.put(i, groupValue);//groupValue } if (LOGGER.isTraceEnabled()){ LOGGER.trace("regexPattern:[{}],input:[{}],groupMap:{}", regexPattern, input, JsonUtil.format(map)); } return map; } /** * 返回在以前匹配操作期间由给定组捕获的输入子序列. * * <p> * 对于匹配器 m、输入序列 s 和组索引 g,表达式 m.group(g) 和 s.substring(m.start(g), m.end(g))是等效的.<br> * 捕获组是从 1开始从左到右的索引.组0表示整个模式,因此表达式 m.group(0)等效于 m.group(). * </p> * * <h3>示例:</h3> * * <blockquote> * * <pre class="code"> * * String regexPattern = "(.*?)@(.*?)"; * String email = "venusdrogon@163.com"; * LOGGER.info(RegexUtil.group(regexPattern, email, 1) + "");//venusdrogon * LOGGER.info(RegexUtil.group(regexPattern, email, 2) + "");//163.com * * </pre> * * </blockquote> * * @param regexPattern * 正则表达式字符串,pls use {@link RegexPattern} * @param input * The character sequence to be matched,support {@link String},{@link StringBuffer},{@link StringBuilder}... and so on * @param group * the group * @return 如果 <code>regexPattern</code> 是null,抛出 {@link NullPointerException}<br> * 如果 <code>input</code> 是null,抛出 {@link NullPointerException}<br> * @see #getMatcher(String, CharSequence) * @see Matcher#group(int) * @since 1.0.7 */ public static String group(String regexPattern,CharSequence input,int group){ Map<Integer, String> map = group(regexPattern, input); return map.get(group); } ``` ## 2.RegexUtil.matches(String, CharSequence)方法 我们常用来做 字符串 匹配正则表达式校验 比如 测试手机号码的单元测试类 https://github.com/venusdrogon/feilong-core/blob/master/src/test/java/com/feilong/core/util/regexutiltest/MobilephonePatternParameterizedTest.java ```JAVA @Parameters(name = "RegexUtil.matches(RegexPattern.MOBILEPHONE, {0})={1}") public static Iterable<Object[]> data(){ String[] valids = { "18501646315", "15001841317", "14701841318" }; String[] invalids = { // "", " ", "1500184131", // count not match " 18501646315", // count not match "18501646315 ", // count not match "10201841318", //no 10 "11201841318", //no 11 "12201841318", //no 12 "16201841318", //no 16 "19201841318" //no 19 }; return TestUtil.toDataList(valids, invalids); } /** * Matches. */ @Test public void matches(){ assertEquals(expectedValue, RegexUtil.matches(MOBILEPHONE, input)); } ``` ## 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()`. **示例:** ```JAVA String regexPattern = "(.*?)@(.*?)"; String email = "venusdrogon@163.com"; RegexUtil.group(regexPattern, email); ``` **返回:** ``` 0 venusdrogon@163.com 1 venusdrogon 2 163.com ```