一、正则表达式技术(Regex)
经典的数据处理技术,数据匹配与查询,数据格式验证,数据清洗等等,被多种语言作为一个工具内置到库里。
系统提供字符处理函数 str族,逐字符偏移比较,效率低下
正则表达式使用贪心算法,完成数据的模式匹配与查询,提高查询效率
即支持精准匹配,也支持模糊查询
正则表达式技术模糊查询,数据要有一定的数据规则,规则越明确正则越简单。若存储没有明确的格式,正则使用不方便。
数据落到磁盘中(持久化处理),如果没有使用数据库,需要设计存储格式,便于后续的使用和访问
1.1 正则的匹配处理流程
1、将数据源以行为单位缓存到模式空间缓冲区,自行遍历迭代直到文件末尾
2、构建描述数据特征的正则语句
3、将缓冲区中待处理数据与正则语句进行贪婪匹配(尽可能多的匹配,提高效率),匹配成功就找到了一条结果
1.2 正则使用方式
1.命令使用
grep '正则语句' FileName
awk
sed
注意:其他命令使用的是通配符,与正则表达式含义不同
2.函数使用
#include <regex.h>
一系列正则函数 regcomp(),regexec(),regexerror()
1.3 正则元字符
\ 转义字符:赋予/取消特殊含义
a* 以前一个表达式(表达式默认的最小颗粒度为1个字符)为参照,表达该表达式出现0次或多次
aa* :a出现1次或多次
a+ 以前一个表达式为参照,表示该表达式出现1次或多次 【需要转义】
a\+ :a出现1次或多次
. 表示任意一个字符
.* 匹配任意一个字符0次或多次
.+ 匹配任意一个字符1次或多次
grep '\.' 查询 .
a? 表示前一个表达式出现0次或1次 【需要转义】
[a] 表达式集合,表示集合中任意一个表达式1次
[abc] a或b或c出现一次,自带逻辑或 |
注意:除了在集合中,其他位置使用逻辑或 | 都 需要转义
[a-zA-Z0-9] 集合扩展 注意:字符集合非词集合
[^a-z] 集合取非,匹配非表达式的任意数据a
^a 后一个表达式为行首
a$ 前一个表达式为行尾
注意:表达式之间无法相互参照,除非此表达式无任何含义
[0-9]{9}$,意思是[0-9]为结尾
\** :0次或多次*
^$ :匹配空行
数据清洗,删除空行到新文件?
grep "^&' file -v > newFile
给你一个time.log,要求匹配5月份的日志,显示共有多少条?
grep '05.\+' time.log | wc -l
管道:两个进程间通信 |
a{n} 限定符,以前一个表达式为参照,连续出现n次 【需要转义】
a{n,} 表达式数据最少出现n次
a{n,m} 表达式数据最少n次,最大m次。匹配颗粒度由大到小
() 创建表达式,括号中的表达式为一个整体,提高表达式的颗粒度 【需要转义】
例:匹配邮箱
^[a-zA-Z0-9_]\{8,15\}@[0-9a-z]\+\.\(com\|cn\)$
匹配手机号
^1[3-9][0-9]\{9\}$
#include <stdio.h>
#include <unistd.h>
#include <regex.h>
#include <string.h>
int main(){
int len;
char buf[1024];
bzero(buf,sizeof(buf));
//正则匹配
regex_t reg; //正则类型
//生成正则类型
// \\* \\? \\{\\} \\(\\) "\"qwq\""
regcomp(®,"^1[3-9][0-9]\\{9\\}$",0); //将字符串正则语句转换为reg正则类
regmatch_t match[1]; //匹配成功传出位置数组
while((len=read(STDIN_FILENO,buf,sizeof(buf)))>0){ //读取标准输入
buf[strlen(buf)-1]='\0'; //取出换行符
if((regexec(®,buf,1,match,0))==0){ //模糊查询,匹配数据,一次返回一条结果
printf("phone %s, success\n",buf);
}
else{
printf("phone %s, failed\n",buf);
}
}
regfree(®); //释放正则
return 0;
}
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <regex.h>
int main(){
char* buf="<address>abc</address>";
int len;
char newbuf[1024];
bzero(newbuf,sizeof(newbuf));
regex_t reg;
regcomp(®,"<address>\\([^<]\\+\\)</address>",0);
regmatch_t match[2];
if((regexec(®,buf,2,match,0)==0)){
snprintf(newbuf,match[1].rm_eo - match[1].rm_so + 1,"%s",buf + match[1].rm_so);
}
printf("%s\n",newbuf);
regfree(®);
return 0;
}