C++正则表达式常用规则及三大算法二

首先,正则表达式我只会三大主要算法,其他的我可能没有了解到,毕竟还没有实战经验。

1.第一算法——匹配算法(  使用函数regex e()与regex_match()   )

  • 顾名思义,是用来匹配检测规则是否合理的逻辑公式
  • 使用到的C++头文件为 iostream,string,regex,以及命名空间 std
  • 接下来将会用两种简单的方式来演示

     ***第一种      (至于匹配结果,我就只用IP地址来验证)

#include<iostream>
#include<string>
using namespace std;


//添加头文件
#include <regex>

//写一个匹配函数
bool IsEmail(string Str)
{
	regex e("\\d+\\.\\d+\\.\\d+\\.\\d"); //IP地址匹配大概、

	//regex e("[a-g]");                    //区间匹配

	//regex e("[a-g]*");                   //*号与区间匹配联合使用

	//regex e("(\\w){4,10}");              //表示4-10个字符 指定个数

	//regex e("ada(e|b)");                 //表示或者

	//regex e("^[a-z]");                   //属于a-a    [^a-z] 不属于a-z

	//regex e("[a-zA-Z][a-zA-Z0-9_]{4,15}");
	bool b = regex_match(Str, e);
		return b;
}
int main(){
	//一个string 类  
	string str;
	cin >> str;
	if (IsEmail(str)){                //根据是否匹配返回对应的输出,当然实际应用中不仅仅如此。
		cout << "This is an email" << endl;
	}
	else cout << "This is not an email" << endl;
	return 0;
	
}

如图第一个大概IP地址匹配可知,为四段数字组成,前三段可以是多个数字,而最后一段只能为一个

故结果如下

    ***第二种

int main(){

	regex e("w*");
	string str;
	cin >> str;
	if (regex_match(str, e)){
		cout << "true" << endl;
	}
	else{
		cout << "false" << endl;
	}


}

如图可知表示一个或多个字母或者数字

结果我就不写了,为了文章简单一点。

2. 第二算法——搜索算法( 使用函数regex e() 与 regex_search()  )

  • 顾名思义,该算法是用于寻找符合条件的字符串
  • 使用了iostream与regex头文件
#include<iostream>
using namespace std;

#include <regex> 
int main(){
	string str("First of of the world."); //在此处可以存放任何想搜索的字符串,当然
    //当然,字符串的赋值还可以 string str = {" First of of the world." };

	regex e("\\b(o)[^ ?.]+");        // ^ 在字符集里面表示的是一个否定

	smatch m;					     //存放string 类型的结果 string类型的迭代器
	while (regex_search(str, m, e)){
		cout << m.str() << "  ";     //打印出该单词
		str = m.suffix().str();      //迭代器的方法,往后面去匹配,如果去掉会形成死循环
	}

    return 0;
	
}

所以,结果如下

 **********************在这里有一个比较有意思的东西 smatch, 那么这个smatch表示什么呢?代码中也说了,smatch是一个迭代器,它是C++11中新加入的正则表达式的支持,由sub_match模板类得来。(如果用Vs的伙伴,可以调试,转义看看) 使用smatch可以实例出一个对象,来保存被表达式所匹配到了的字符串。

3.第三大算法——替换算法(使用regex e() 与regex_replace以及文件操作函数)

  • 顾名思义,需要从某一地方找出符合规则的字符串,并且将它替换掉
  • 由于该操作我没有用在高难度方面,我就用文件流来写
  • 使用的头文件 iostream,regex,string,fstream,以及命名空间std
  • 前提准备,在资源文件夹建立一个txt(其它文件类型对应代码改变)
#include<iostream>
#include<regex>
#include<string>
#include<fstream>
using namespace std;


int main(){
	string  Str;
//打开文件 以二进制,读的方式
	fstream File("Swap.txt", ios::in | ios::binary);

	// 1.知道文件大小
	File.seekg(0, SEEK_END);

	size_t a = File.tellg();

	File.seekg(0, SEEK_SET);

	char szTemp[1024] = { 0 };

	File.read(szTemp, sizeof(char)*a);

	Str += szTemp;
//关闭文件
	File.close();

	regex e("\\b(sf)[^ .?]*");   //此处为定义需要被替换的字符串

	string s;

    //此处Family为替换之后的字符串
	regex_replace(back_inserter(s), Str.begin(), Str.end(), e , "Family"); 

	cout << s << endl;

//打开文件 以写的二进制格式
	fstream File1("Swap.txt", ios::out | ios::binary);
	File1.write(s.c_str(), s.size());
	File1.close();

	

	return 0;
}

  如下图,上面是修改后,下方是修改前的

PS: 文件操作就不说了(调皮) ,加油!

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
正则表达式转化为DFA的过程可以分为以下几步: 1. 将正则表达式转化为NFA(非确定性有限状态自动机)。 2. 将NFA转化为DFA(确定性有限状态自动机)。 3. 对DFA进行最小化,去除无用状态。 具体步骤如下: 1. 将正则表达式转化为NFA 首先,将正则表达式转化为后缀表达式(也叫逆波兰表达式),然后构建NFA。 例如,对于正则表达式 a*|b,其后缀表达式为 a* b |。构建NFA的过程如下: 1)对于每个字符,创建一个状态,并在该状态上添加一个转移,转移到下一个字符状态。 2)对于每个 *,创建两个状态,分别表示该字符可以出现 0 次或多次。在这两个状态之间添加一个 ε 转移。 3)对于每个 |,创建两个新状态,分别表示两条路径。在这两个状态之间添加一个 ε 转移。 最终得到的NFA如下图所示: ![NFA](https://i.loli.net/2021/04/28/BxAspJt9Xn8RbFV.png) 2. 将NFA转化为DFA 在将NFA转化为DFA之前,需要先了解一下 ε-闭包和 ε-转移。 ε-闭包:从一个状态开始,通过 ε 转移可以到达的所有状态的集合。 例如,对于上图中的状态 1,其 ε-闭包为 {1,2,4}。 ε-转移:从当前状态通过 ε 转移可以到达的所有状态。 例如,对于上图中的状态 1,在读入字符 a 后可以到达的状态为 {1,2,4},其 ε-转移为 {2,4}。 接下来,对于每个状态,找出它的 ε-闭包和从该状态出发读入字符后可以到达的状态,然后将这些状态合并为一个新的 DFA 状态。 例如,对于上图中的 NFA,可以得到以下 DFA: ![DFA](https://i.loli.net/2021/04/28/LxXZV7rW8Jv2Qam.png) 3. 对DFA进行最小化 最小化 DFA 的目的是去除无用状态,减少状态数目。最小化 DFA 的过程可以使用 Hopcroft 算法或 Moore 算法等。 最终得到的最小化 DFA 如下图所示: ![最小化DFA](https://i.loli.net/2021/04/28/N6Ggx4A5wOoV7JY.png) 至此,正则表达式转化为 DFA 的过程就完成了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值