现在的位置: 首页 > 综合 > 正文

支持通配符的字符串比较——POSIX函数fnmatch

2013年08月02日 ⁄ 综合 ⁄ 共 1685字 ⁄ 字号 评论关闭
以前做字符串比较,如果要支持通配符,除非用正则表达式的一些库,否则非得自己好好编码一番不可。

今天无意间在浏览mod_ssl的代码更新时,发现它比较带有通配符的域名(如*.sina.com.cn)时,使用了一个名为apr_fnmatch的函数:
    if (apr_fnmatch_test(cn)) {
        int fnm_flags = APR_FNM_PERIOD|APR_FNM_CASE_BLIND;
       
        if (apr_fnmatch(cn, s->server_hostname, fnm_flags) == APR_FNM_NOMATCH) {
            ...
        }
    }

apr_fnmatch函数的声明和实现在libapr(Apache Portable Runtime)的apr_fnmatch.h文件中

#define APR_FNM_NOMATCH     1     /**< Match failed. */
 
#define APR_FNM_NOESCAPE    0x01  /**< Disable backslash escaping. */
#define APR_FNM_PATHNAME    0x02  /**< Slash must be matched by slash. */
#define APR_FNM_PERIOD      0x04  /**< Period must be matched by period. */
#define APR_FNM_CASE_BLIND  0x08  /**< Compare characters case-insensitively.
                                   * @remark This flag is an Apache addition
                                   */

/**
 * Try to match the string to the given pattern, return APR_SUCCESS if
 *    match, else return APR_FNM_NOMATCH.
 * @param pattern The pattern to match to
 * @param strings The string we are trying to match
 * @param flags flags to use in the match.  Bitwise OR of:
 * <PRE>
 *              APR_FNM_NOESCAPE       Disable backslash escaping
 *              APR_FNM_PATHNAME       Slash must be matched by slash
 *              APR_FNM_PERIOD         Period must be matched by period
 *              APR_FNM_CASE_BLIND     Compare characters case-insensitively.
 * </PRE>
 */

APR_DECLARE(apr_status_t) apr_fnmatch(const char *pattern,
                                      const char *strings, int flags);

而源代码文件apr_fnmatch.c的一开头,就发现这样一句注释:

/*
 * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
 * Compares a filename or pathname to a pattern.
 */
也即fnmatch是一个posix函数。

在Linux命令行下执行man fnmatch,果然出现了对应的manual,函数原型和各个标志位的定义均和pr_fnmatch一致,也就是说,在Linux环境下,只需要包含头文件fnmatch.h,就可以使用此函数来完成支持通配符的字符串比较。
 

抱歉!评论已关闭.