请实现一个函数来匹配包括’.’和’‘的正则表达式,其中匹配是指字符串的所有字符匹配整个模式串。具体匹配规则如下:模式串中的字符’.’表示任意一个字符,而’‘表示它前面的字符可以出现任意次(包含0次。例如,字符串”aaa”与模式”a.a”和”ab*ac*a”匹配,但是与”aa.a”和”ab*a”均不匹配。
为了方便说明,str 表示字符串,pattern 表示模式串
bool match_core (char *str, char *pattern);
1、首先考虑递归出口:
当 *str == '\0' && *pattern == '\0' 时,即 str 和 pattern 都是空串时,我们说它们是匹配的,返回 true;
当 *str != '\0' && *pattern == '\0',str 无法完成匹配,返回 false.
【注意】当 *str =='\0' && *pattern != '\0' 时,是有可能匹配成功的,比如:pattern 为 a*,而 str 为空串时,是可以匹配成功的。因为 ‘*’ 前面的字符 a 可以出现0次。
2、我们可以将匹配过程分为两类:一类是(pattern + 1) != ‘‘;另一类是(pattern + 1) == ‘‘,下面基于这两种情况讨论该问题的具体实现:
当*(pattern + 1) != '*' 时,只要 *str 与 *pattern 匹配,两个字符串分别向前移动一步。即:
若 *str == *pattern, 则 match_core (str + 1, pattern + 1);
若 *str != '\0' && *pattern == '.',则 match_core (str + 1, pattern + 1);
若 *str 和 *pattern 不满足上述两个条件,说明 *str 和 *pattern 不匹配,直接返回 false。
当 *(pattern + 1) == '*' 时,根据 *pattern 与 *str 匹配的个数,可以分为下面几种情况:
若匹配个数为0,即 *pattern 与 *str 不匹配,则match_core (str, patten + 2);
若匹配个数为 1 个或多个,我们只需要每次将 str 向前移一步,pattern 保持原来的位置,继续做下一轮匹配,即match_core (str + 1, pattern)。
我们考虑这种情况:str = “aaaaa”, pattern = “aa*a”,按照题目叙述的匹配原则,str 与 pattern 应该是匹配的,但是按照我们刚才分析的思路走下来,match_core返回的是false,分析明显是由漏洞的,我们再来看看(pattern + 1) == ‘‘中匹配个数是多个的情况,我们不仅要考虑 str + 1 与 pattern 的匹配, 还要考虑到 str 与 pattern + 2 的匹配情况,只要这两种情况中的任何一种匹配成功, str 和 pattern 都算是匹配成功。
//正则表达式匹配核心部分
bool match_core (char *str, char *pattern)
{
//*pattern == '\0'的两种情况已经分析完,下面的情况肯定是*pattern != '\0'
if (*str == '\0' && *pattern == '\0')
{
return true;
}
if (*str != '\0' && *pattern == '\0')
{
return false;
}
//下面来分析pattern没有走完的情况
//分为两种情况:一个是模式串的下一个字符为*;另一种是模式串的下啊一个字符不为*
if (*(pattern + 1) != '*')
{
if (*str == *pattern || (*str != '\0' && *pattern == '.'))
{
return match_core(str + 1, pattern + 1);
}
else
{
return false;
}
}
else
{
if (*str == *pattern || (*str != '\0' && *pattern == '.'))
{
return match_core (str, pattern + 2) || match_core (str + 1, pattern);
}
else
{
return match_core (str, pattern + 2);
}
}
}
bool match (char *str, char *pattern)
{
if (str == NULL && pattern == NULL)
{
return true;
}
if (str == NULL || pattern == NULL)
{
return false;
}
return match_core (str, pattern);
}