正则表达式简介以及C++/Java实现

前端之家收集整理的这篇文章主要介绍了正则表达式简介以及C++/Java实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

由于最近的项目中用到了正则表达式,正好也遇到了一个面试题,题中也有对正则表达式就行考察,所以简单学习一下Regular Expression,然后以一道笔试题的实现来作为练习。

首先可以熟悉一下正则表达式的概念:http://baike.baidu.com/view/94238.htm

常用的正则表达式
正则表达式 匹配 举例
x 指定字符x Java 与 Java 匹配
. 任意单个字符 Java 与 J..a匹配
(ab|cd) ab或cd ten与t(en|im)匹配
[abc] a,b或c Java与Ja[uvwx]a匹配
[^abc] 除a,b或c以外的任何字符 Java与Ja[^ars]a
[a-z] a到z Java与[A-M]av[a-d]匹配
[^a-z] 除a-z之间的任何字符 Java与Java[^b-d]匹配
[a-e[m-p]] a到e或m到p Java与[A-G[I-M]]av[a-d]匹配
[a-e&&[c-p]] a-e与c-p的交 Java与[A-P&&[I-M]]av[a-d]匹配
\d 一个数字,[1-9] Java2与"Java[\\d]"匹配
\D 非数字 $Java与"[\\D][\\D]ava"匹配
\w 词的一个字符 Java与"[\\w]ava"匹配
\W 非词的一个字符 $Java与"[\\W][\\w]ava"匹配
\s 一个空白字符 "Java 2"与"Java\\s2"匹配
\S 一个非空白字符
p* 模式p的0次或多次出现
p+ 模式p的1次或多次出现
p? 模式p的0次或1次出现
p{n} 模式p的n次精确出现
p{n,} 模式p的至少n次出现
p{n,m} 模式p的n到m次(包含m和n)出现

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)
功能:
将要进行匹配的正则表达式pattern进行编译,做匹配前的准备工作
int regexec(const regex_t *compiled,const char *target,size_t nmatch,regmatch_t pmatch[],int eflags)
功能:
用来检测字符串target是否匹配正则表达式compiled


那么,现在就根据那道题目将代码附上(其中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][\\d\\w\\.]{1,17}@[\\d\\w\\.]{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 = "[\\d\\w\\.\\_]*+@+[\\d\\w\\.]*";  //定义模式串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.jb51.cc/article/p-udyrqdln-mp.html

猜你在找的正则表达式相关文章