对于 scanf 家族系列函数( scanf, fscanf, sscanf, vscanf, vsscanf, vfscanf),相信大家对它们常见的格式化输入已十分熟悉。 但是, scanf 系列函数,还有一个特殊的用法,该用法能够实现简单的字符过滤功能,类似正则表达式,您是否知道呢? scanf 函数还能实现正则表达式?让我们往下看吧^_^
这个特殊的格式,就是“[ ]”,一对中括号,支持简单的正则表达式功能,比如 "%[^a-z]" 将忽略所有的 a-z 的小写字母; "%[A-Z]" 将只接收 A-Z 的大写字母。学过正则表达式的同学,一看这个用法,就会觉得那么的亲切^_^。
scanf 家族函数(scanf, fscanf, sscanf, vscanf, vsscanf, vfscanf)都支持这种特殊功能,虽然不如真正的正则表达式那么强大,但是如果运用灵活,在验证要求不高的场景下,这个特性还是能够为我们节省不少精力的,杀鸡焉用牛刀!让我们一睹该特性的强大之处吧!(从函数单一性考虑, scanf 家族函数的功能太过强大了,呵呵)
下面我们以检查电子邮箱地址的合法性为例,进行说明,假设合法 Email 地址的用户名和域名均是由数字、字母、中划线、下划线、圆点组成,其他字符均为非法字符。
源码如下:
/******************************************************************************
Copyright by Javacode007, All rights reserved!
Filename : scanf_printf.c
Author : Javacode007
Date : 2012-8-22
Version : 1.0
Description : scanf系列函数实现简单正则表达式
******************************************************************************/
#include <stdio.h>
#include <string.h>
int isValidEmail(const char *pcEmailaddr)
{
/* 假定用户名和服务器域名的地址最大值不超过127个字符 */
char user[128] = {0};
char site[128] = {0};
if(NULL == pcEmailaddr)
{
return 0;
}
/* 设定合法 Email 地址的用户名和域名均是由数字、字母、中划线、下划线、圆点组成 */
sscanf(pcEmailaddr, "%[0-9a-zA-Z-_.]%[@0-9a-zA-Z._]", user,site);
//printf("user=%s, site=%s\r\n", user, site);
if(0 < strlen(user) && 0 < strlen(site) && ((strlen(user) + strlen(site)) == strlen(pcEmailaddr)))
{
if('@' == site[0])
{
return 1;
}
}
return 0;
}
int main()
{
const char* pacEmailaddrs[] = {"[email protected]", "some_bodycsdn.net", "some_body#@csdn.net",\
"[email protected]", "[email protected]"};
int i = 0;
int len = sizeof(pacEmailaddrs)/sizeof(*pacEmailaddrs);
for(i = 0; i < len; i++)
{
printf("\"%s\" is %s Email.\r\n", pacEmailaddrs[i], isValidEmail(pacEmailaddrs[i])?"Valid":"Invalid");
}
return 0;
}
输出结果如下: