自定义正则表达式的匹配算法
- 前言
- 一、题目
- 二、匹配算法
- 总结
- 参考文献
前言
自定义正则表达式规则,然后完成匹配算法的实现。
一、题目
二、匹配算法
匹配的四种情况,把每种情况写好就OK了。
1)情况1:递归出口1,规则末尾,表达式未末尾,返回false。
2)情况2:递归出口2,规则末尾,表达式末尾,返回true。
3)情况3:递归出口3,规则未末尾,表达式末尾,此时的规则必须是带*号的。
4)情况4:正式递归1,规则未末尾,表达式未末尾,此时要根据是否有’*‘来for循环递归,或者无’*‘的简单递归。
package com.xhu.offer.top100;
//正则表达式匹配
public class IsMatch {
//模拟+分类归纳
public boolean isMatch(String s, String p) {
//如果两个字符串相等,直接返回true。
// 相等有两者方式,1-内容相等;2-以.*的方式匹配全内容。
if (".*".equals(s) || s.equals(p)) return true;
//进行逐位模拟
return dfs(s, p, 0, 0);
}
/**
* 对字符串s和字符串p进行逐位匹配
*
* @param i 字符串需匹配的下标
* @param j 规则需匹配的下标
* @param s 需匹配字符串
* @param p 匹配的规则
*/
private boolean dfs(String s, String p, int i, int j) {
//j到规则末尾,i到字符串末尾,则为第一个递归出口,匹配成功。
if (j >= p.length() && i >= s.length()) return true;
//j到规则末尾,i到字符串末尾,则为第二个递归出口,匹配失败。
if (j >= p.length() && i < s.length()) return false;
//j没有到规则末尾,i到规则末尾,则规则从j位开始,只有每两位都是一个字符一个*号才能匹配成功,否则匹配失败。
if (j < p.length() && i >= s.length()) {
for (int k = j; k < p.length(); k += 2) {
if (k + 1 == p.length() || p.charAt(k + 1) != '*') return false;
}
return true;
}
//j没有到规则末尾,i也没到规则末尾。
//根据当前位是否为点号和下一位是否为*来做出相应的处理。
//后面有*,需要进行for循环匹配的情况。
if (j + 1 < p.length() && p.charAt(j + 1) == '*') {
boolean flag = false;
//先把特殊情况做了,即*匹配0个字符。
if (dfs(s, p, i, j + 2)) return true;
//其它情况。
for (int k = i; k < s.length(); k++) {
if (p.charAt(j) == '.' || p.charAt(j) == s.charAt(k)) flag = dfs(s, p, k + 1, j + 2);
else return false;
if (flag) return true;//已经匹配成功,就直接返回true。
}
} else {//后面没有字符了,或者就算有,后面那个字符也不是*,则简单匹配一下。
char cp = p.charAt(j);
if ('.' == cp || cp == s.charAt(i)) return dfs(s, p, i + 1, j + 1);
}
return false;
}
}
总结
1)静下来认真刨析问题,完成问题拆解和分类。
2)递归和DFS思想很重要。
参考文献
[1] Leetcode 原题