19: 正则表达式的匹配

正则表达式的匹配

实现一个函数,用来匹配包含.*的正则表达式匹配。
.匹配任意一个字符 ,而* 表示当前字符的0次或多次
首先要把下个字符是*的情况区分出来,因为 a*可以匹配一个a, 多个a, 不匹配

当下个字符是* 时,如果pattern和当前字符匹配,不能简单的进入pattern=*的状态,分三种路径

  1. 匹配一个ch,并进入下一个
  2. 匹配多个ch,停留在该状态
  3. 不匹配,直接跳入下一个状态

下个字符不是*的情况,再和ch or . 匹配

没想到的地方是,按照书上的方法,java不能处理 字符串是"" 而pattern是.* 的情况,在过程上来说应该是能够匹配,才输出true。错误点出现在空指针异常上(str是空字符的情况下直接访问str[0]),因为java严格禁止指针越界的原因,所以在判断条件之前加了长度的判断。
这种情况是忽略.*, 再跳到字符串匹配到末尾,模式匹配到末尾来退出,不存在进入哪个状态的过程。这样虽然过程上不正确,但是能保证逻辑上正确。也就是匹配。

public static boolean match(String str, String pattern) {
    if (str == null || pattern == null)
        return false;

    return matchCore(str.toCharArray(), pattern.toCharArray(), 0, 0);
}

public static boolean matchCore(char[] str, char[] pattern, int s, int p) {
    if (s == str.length && p == pattern.length)
        return true;

    if (s < str.length && p == pattern.length)
        return false;

    if ((p + 1) < pattern.length && pattern[p + 1] == '*') {
        if ( s < str.length && (pattern[p] == str[s] || pattern[p] == '.')) {
            return matchCore(str, pattern, s + 1, p + 2) ||  //匹配一个字符
                matchCore(str, pattern, s + 1, p) || //匹配多个字符
                matchCore(str, pattern, s, p + 2); //不匹配字符
        } else {
            return matchCore(str, pattern, s, p + 2); //只能不匹配
        }
    }

    if (s < str.length && (pattern[p] == str[s] || pattern[p] == '.')) {
        return matchCore(str, pattern, s + 1, p + 1);
    }
    return false;
}
表示数值的字符串

实现一个函数来判断一个字符串是否表示数值。
+100, 5e2, -123, 3.14, -1E-16 都表示数值

向正则表达式疯狂低头!

public static boolean isNumberic(char[] str) {
    if (str == null || str.length == 0) {
        return false;
    }
    return new String(str).matches("[+-]?\\d*(\\.\\d+)?([eE][+-]?\\d+)?");
}

其中[+-] 表示一个符号的集合
[+-]?表示这个集合中的元素出现0或1次
\\d*表示 0~9 的数字出现 0次或n次
\\d+ 1~n次
\\. 转义后的.
(\\.\\d+)? 表示(\\.\\d+)这个组合出现0~1次 (就是说小数部分可有可无, 如果有只能出现一次)
([Ee][+-]?\\d+)? 表示的是指数部分可由可无,其组成必须由E/e和数字组成,其中±号可以省略

正则表达式是真的屌

猜你喜欢

转载自blog.csdn.net/weixin_41889284/article/details/89417927