Skip to content

正则表达式工具类 RegexUtil

feilong edited this page May 22, 2020 · 1 revision

1.前言

在文本处理中,正则表达式几乎是全能的,但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();
	}

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

    /**
     * 编译给定正则表达式 <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 = "[email protected]";
     * RegexUtil.group(regexPattern, email);
     * </pre>
     * 
     * <b>返回:</b>
     * 
     * <pre class="code">
     *    0 [email protected]
     *    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 = "[email protected]";
     * 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

    @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().

示例:

 String regexPattern = "(.*?)@(.*?)";
 String email = "[email protected]";
 RegexUtil.group(regexPattern, email);

返回:

    0 [email protected]
    1 venusdrogon
    2 163.com

core

Clone this wiki locally