以前做字符串比较,如果要支持通配符,除非用正则表达式的一些库,否则非得自己好好编码一番不可。
今天无意间在浏览 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,就可以使用此函数来完成支持通配符的字符串比较。
今天无意间在浏览 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,就可以使用此函数来完成支持通配符的字符串比较。