正则表达式简介以及C++/Java实现
由于最近的项目中用到了正则表达式,正好也遇到了一个面试题,题中也有对正则表达式就行考察,所以简单学习一下Regular Expression,然后以一道笔试题的实现来作为练习。 首先可以熟悉一下正则表达式的概念:http://baike.baidu.com/view/94238.htm
e.g1:社会安全数字的模式为
xxx-xx-xxxx,其中x为一个
数字。社会安全数字的一个正则表达式可以描述为:
[d]{3}-[d]{2}-[d]{4}
e.g2:一个以0,2,4,6,8结尾的偶数,偶数的模式可以描述为:
[d]*[02468]
e.g3:电话号码的模式为(xxx)xxx-xxxx,其中x为数字,第一个数字不能为0。电话号码的正则表达式可表示为:
([1-9][d]{2})[d]{3}-[d]{4}
备注:括号()是特殊的符号,在正则表达式中用来把模式分组。在正则表达式中若表示(或),必须使用(和)。
e.g4:假设姓包括25个子母中的大部分,第一个部分大写。姓的模式可以描述为:
[A-Z][a-zA-Z][1,24]
注意,不能在正则表达式中使用任意空白。例如,[A-Z][a-zA-Z]{1.24}是错的。
e.g5:"Welcome to (Java|HTML)"匹配的是:"Welcome to Java"或"Welcome to HTML"
e.g6:和所有字符串匹配的正则表达式是
".*"。
下面是某个IT公司的笔试题:
Please write a program to complete the following task (C++/Perl/Python/Shell allowed): Read several lines of text from STDIN,and 1)filter out all the email addresses from the input text; 2)print a statistic table of how many times each email server is used. Example: Input: CEO of NVIDIA: jenhsun.huang@nvidia.com (the address if fake :) Some of my favorite writers (they are all fake :) scott.meyers@brown.edu herb_sutter@dev.microsoft.com ericgamma@google.com - known as GoF jcarmack@idsoftware.com mark_kilgard@nvidia.com andrew.rubin@google.com NVIDIA recruiting team: hr@nvidia.com Output: 1) jenhsun.huang@nvidia.com scott.meyers@brown.edu herb_sutter@dev.microsoft.com ericgamma@google.com jcarmack@idsoftware.com mark_kilgard@nvidia.com andrew.rubin@google.com hr@nvidia.com 2) nvidia.com: 3 google.com: 2 brown.edu: 1 dev.microsoft.com: 1 idsoftware.com 1
程序流程: 1)将文本文件标准读入。 2)对于输入的字符串判断是不是和正则表达式匹配(Email的正则表达式),如果匹配进入3),否则2)。 3)将匹配的字符串(说明是Email)的"@"字符之后的子串提取出来,然后用map存储子串。 4)统计相同子串出现的次数,按照次数进行排序。 5)将map中的<key,value>对输出到文件中。
Java中的正则表达式判断: Java中的正则表达式判断很简单,假设目标串为target,正则表达式模式串为pattern,那么判断二者匹配的方法为:target.match(pattern),如果返回真则表示匹配成功。
C中的正则表达式的判断: C中的正则表达式的判断则相对复杂,首先要将正则表达式模式串pattern编译成为一个结构体compiled,然后将目标串target与compiled进行匹配。主要的两个函数为: int regcomp(regex_t *compiled,const char *pattern,int cflags)
那么,现在就根据那道题目将代码附上(其中regular_expression.txt文件就是题目中input的内容): Java实现:
package String; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.Map.Entry; public class Regex { private static class ValueComparator implements Comparator<Map.Entry<String,Integer>>{ @Override public int compare(Map.Entry<String,Integer> m,Map.Entry<String,Integer> n) { return n.getValue()-m.getValue(); } } public static void main(String [] args) throws FileNotFoundException{ //6~18个字符,可使用字母、数字、下划线,需以字母开头 String pattern = "^[a-zA-Z][dw.]{1,17}@[dw.]{1,}"; //定义模式串pattern File file = new File("regular_expression.txt"); Scanner input = new Scanner(file); HashMap map = new HashMap<String,Integer>(); int val; while(input.hasNext()){ //依次读入文件中的字符串 String s = input.next(); s.trim(); if(s.matches(pattern)){ //如果是匹配则说明是email System.out.println(s); s = s.substring(s.lastIndexOf('@')+1); //提取"@"字符后面的子串 if(map.get(s)==null){ map.put(s,1); }else{ val = (Integer)map.get(s)+1; map.put(s,val); } } } ArrayList<Map.Entry<String,Integer>> list = new ArrayList<Map.Entry<String,Integer>>(map.entrySet()); Regex.ValueComparator vc = new ValueComparator(); Collections.sort(list,vc); //按照value值进行排序 Iterator listItr = list.iterator(); //迭代输出结果 while(listItr.hasNext()){ Map.Entry<String,Integer> entry = (Map.Entry<String,Integer>) listItr.next(); System.out.println(entry.getKey()+" : "+entry.getValue()); } } }
C/C++实现:
#include<iostream> #include<stdio.h> #include<regex.h> #include<string.h> #include<fstream> #include<map> #include<vector> #include<algorithm> using namespace std; int cflags = REG_EXTENDED,valid,i; regex_t compiled; const char *pattern = "[dw._]*+@+[dw.]*"; //定义模式串pattern char *target = new char[100]; ifstream fin; ofstream fout; map<string,int> map_regex; typedef pair<string,int> PAIR; struct CmpByValue { bool operator()(const PAIR& lhs,const PAIR& rhs) { return lhs.second > rhs.second; } }; void OutputResults() { vector<PAIR> vector_regex(map_regex.begin(),map_regex.end());//将map_regex中的内容转存到vector_regex中去。 sort(vector_regex.begin(),vector_regex.end(),CmpByValue());//根据比较函数进行排序 for(int i=0;i<vector_regex.size();i++) { fout<<vector_regex[i].first<<" : "<<vector_regex[i].second<<endl; } } void RegexMatch(char * target) { regcomp(&compiled,pattern,cflags); valid = regexec(&compiled,target,NULL,0); if(valid == REG_NOMATCH) { //cout<<"no match"<<endl; } else if(valid == 0) { cout<<target<<" matches "<<pattern<<endl; string::size_type pos; string target_str(target); string sub_str; pos = target_str.find("@"); sub_str = target_str.substr(pos+1,target_str.length()-pos-1);//提取子串 //统计子串出现的频率 if(map_regex[sub_str]==0) { map_regex[sub_str]=1; } else { map_regex[sub_str]++; } } regfree(&compiled); } int main(int argc,char ** argv) { fin.open("regular_expression.txt"); if(!fin) { cout<<"open the file failure"<<endl; return 0; } fout.open("result.txt"); while(fin>>target) { RegexMatch(target); } OutputResults(); fin.close(); fout.close(); return 0; }
输出文件result.txt:
jenhsun.huang@nvidia.com scott.meyers@brown.edu herb_sutter@dev.microsoft.com ericgamma@google.com jcarmack@idsoftware.com mark_kilgard@nvidia.com andrew.rubin@google.com hr@nvidia.com nvidia.com : 3 google.com : 2 brown.edu : 1 dev.microsoft.com : 1 idsoftware.com : 1 参考:
http://www.wuzesheng.com/?p=929
http://see.xidian.edu.cn/cpp/html/1428.html
转载注明出处:http://www.52php.cn/article/p-udyrqdln-mp.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |