正则表达式的匹配
实现一个函数,用来匹配包含
.
和*
的正则表达式匹配。
.
匹配任意一个字符 ,而*
表示当前字符的0次或多次
首先要把下个字符是*
的情况区分出来,因为a*
可以匹配一个a, 多个a, 不匹配
当下个字符是*
时,如果pattern和当前字符匹配,不能简单的进入pattern=*的状态,分三种路径
- 匹配一个ch,并进入下一个
- 匹配多个ch,停留在该状态
- 不匹配,直接跳入下一个状态
下个字符不是*
的情况,再和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和数字组成,其中±号可以省略
正则表达式是真的屌