代码之家  ›  专栏  ›  技术社区  ›  Aemilius

通配符匹配字符串

  •  0
  • Aemilius  · 技术社区  · 6 年前

    我正在尝试编写一个函数 bool match(char pattern[], char expresssion[]) 检查模式是否与表达式匹配。如果 * 出现在模式中,它可以与任何字符串匹配,也可以与空字符串匹配。这就是我的问题所在。

    我想迎合这位明星。我的第一个想法是检查星星后面出现的下一个字符,看看它是否出现在表达式中。如果它出现在第n个位置,我将在模式中移动一个字符,并开始从第n个位置进一步检查表达式。然而,我应该从左边还是从右边检查我的表情并不总是很明显。例如,如果从左侧检查,则此测试将失败:

    match("a*b", "ababab")
    

    因为只有第一个“b”会被恒星“吞噬”。相反,如果我从右侧进行检查,则此测试将失败:

    match("a*b*b*", "abbbbbbbba")
    

    你能告诉我怎么对付这位明星吗?

    1 回复  |  直到 6 年前
        1
  •  3
  •   laker93    6 年前

    诀窍是编写一个递归函数并将字符逐个匹配,直到找到' * '. 一次' * '遇到了什么都是公平的游戏,所以你可以返回true。

    bool match(char const *pattern, char const *file) {
        for (; *pattern != '\0'; ++pattern) {
            switch (*pattern) {
            case '*': {
                //if pattern terminates after * then file can be anything, thus
                //terminate and return true.
                if (pattern[1] == '\0')
                    return true;
                //pattern doesn't terminate so cut off '*' from pattern,
                //increment file and repeat.
                size_t max = strlen(file);
                for (size_t i = 0; i < max; i++)
                    if (match(pattern + 1, file + i))
                        return true;
                return false;
            }
            default:
                //if pattern doesn't specify a '?' or a '*', it must be a regular
                //character and so, must require a like for like match with file.
                if (*file != *pattern)
                    return false;
                ++file;
            }
        }
        //we have iterated through the whole of pattern and so file must end too
        //if we are to match.
        return *file == '\0';
    }
    

    然后,您可以向switch语句添加额外的分支,并向glob工具添加功能。例如,尝试添加' ? '.