关于正则表达式的由来及所有语法在这里不做介绍,大家可以参照下面网址中给出的例子。
http://www.jb51.net/tools/zhengze.html
这里将我程序中涉及到的内容,作为一个例子写出来:
首先,大家都知道正则表达式最核心的工作就是可以匹配文本,那么我们也就可以利用正则表达式来提出文件中的“脏数据”
待处理的数据如下:
146573.100000 31.6574165859 120.7748939130 12.4263735032 350.1498296816 0.5574414962 -0.0871731270
573495.3524453273 3504188.5562077025
246573.100000 31.6574165859 120.7748939130 12.4263735032 350.1498296816 0.5574414962 -0.0871731270
573495.3524453273 3504188.5562077025
346573.100000 31.6574165859 120.7748939130 12.4263735032 350.1498296816 0.5574414962 -0.0871731270
573495.3524453273 3504188.5562077025
?8237.650000 31.6545634665 120.7780329667 11.3441768121 294.4719277869 1.7129763084 -3.3858530746
573795.3412689130 3503874.2990623275
%48237.70000 31.6545642402 120.378031?03 11.3452082761 2?.4738409254 1.7228125240 -3.3825053331
5?795.1721630698 3503874.3836538661
446573.100000 31.6574165859 120.7748939130 12.4263735032 350.1498296816 0.5574414962 -0.0871731270
573495.3524453273 3504188.5562077025
546573.100000 31.6574165859 120.7748939130 12.4263735032 350.1498296816 0.5574414962 -0.0871731270
573495.3524453273 3504188.5562077025
可以,看到我们数据中第四行、第五号产生了脏数据。为此我们就要利用正则表达式来过滤文本内容。
1、包含头文件
#include<regex>
2、定义正则表达式函数
bool is_xy_vaild(char * xy) { regex pattern("(\.){99}(\\d{6})(\\.)(\\d{10})(\.)(\\d{7})(\\.)(\\d{10})(\\s{1,2})"); return regex_match(xy,pattern); }
关于(\.){99}(\\d{6})(\\.)(\\d{10})(\.)(\\d{7})(\\.)(\\d{10})(\\s{1,2}) 正则表达式解释如下:
()代表正则表达式的一个个子表达式
第1个(\.)表示匹配除“\n”之外的任何单个字符
第2个(99)表示匹配99个任意单个字符
(由于待处理数据我们只关心最后两项X,Y,我们可以跳过前面99个字节的数据)
第3个(\\d{6})表示匹配6个任意数字
第4个(\\.)表示匹配“.”
第5个(\\d{10})表示匹配10个任意数字
至此我们就成功的完成了对原数据中第六列X坐标的匹配工作。
第6个(\.)表示匹配任意字符
……
(\\s{0,2})匹配任何空白字符,包括空格、制表符、换页符,{0,2},匹配0~2次
其实,在正则表达式的语法中,代码与说明的对照如下:
代码 |
说明 |
. |
匹配除换行符以外的任意字符 |
\s |
匹配任意的空白符 |
\d |
匹配数字 |
C++代码于此的区别主要是由于“转义字符”所引起,转义字符“\”表示后面的的字符,都不是它本来的ASCII字符意思了。
(\.)表示的不是一个字符“.”而是对应的正则表达式中“匹配除换行符以外的任意字符”的含义。
\\则代表一个反斜线字符'\'(或理解为\\表示扔掉第二个\的转义特性),(\\d)就对应正则表达式中“匹配数字”的含义
3、主函数中的调用
int _tmain(int argc, _TCHAR* argv[]) { FILE *myFile=fopen("10.txt","rb"); char buf[200]; memset(buf,0,200); if(!myFile){ cout<<"打开失败"<<endl; exit(1); } int errorCount=0; while(1){ fgets(buf,200,myFile); if(is_email_vaild(buf)){ cout<<"格式正确"<<endl; } else{ cout<<"格式错误"<<endl; errorCount++; } memset(buf,0,200); } cout<<"出现错误的数据条数"<<errorCount<<endl; return 0; }
输出结果:
注:最后匹配(\\s{0,2})的原因在于使用"r","rb"的方式打开文件时,buf中的字节数并不相等
在使用二进制方式打开文件时,遇到换行会解释为 "13","10"l两个字符,分别代表“换行”,“回车”
使用文本方式打开文件时,遇到换行则解释为"10"一个字符。
当遇到文档结尾时,没有换行以及回车字符匹配。