URL映射 201803-3 C++

本文介绍了一个程序,该程序基于正则表达式解决URL映射问题。它读取规则和输入URL,通过匹配规则的正则表达式来确定输入URL的对应名称和参数。程序首先转换规则,然后使用regex_match进行匹配,输出匹配结果或404。核心数据结构是存储规则的vector<pair<string,regex>>。
摘要由CSDN通过智能技术生成


一、题目

在这里插入图片描述

在这里插入图片描述

原题目链接

二、解题

1.题目

这个程序解决了一个URL映射的问题。它读入一组规则,每条规则定义了一种URL模式和它对应的名称。然后程序读入一组输入URL,并将它们与规则进行匹配。如果一个输入URL与某条规则匹配,则程序输出该规则对应的名称以及从URL中提取出的参数。如果一个输入URL与任何一条规则都不匹配,则程序输出"404"。

这个程序背后的原理是使用正则表达式来匹配URL。每条规则都定义了一个正则表达式,用于描述URL模式。程序使用正则表达式匹配函数regex_match来检查输入URL是否与规则的正则表达式匹配。如果匹配成功,函数会返回true并将匹配结果存储在一个smatch对象中。程序可以通过访问这个对象来获取匹配结果中的子匹配。

2.代码

dev c++ 5.11

#include<iostream>
#include<vector>
#include<regex>
using namespace std;
inline bool isStringDigit(const string &s){
	for(char c:s) if(c<'0'||c>'9') return 0;
	return 1;
}
int main(){
	int n,m;
	string p,r; 
	cin>>n>>m;
	vector<pair<string,regex>> rules;//存储URL规则,映射为规则名->规则的正则表达式
	vector<pair<regex,string>> trans={//转换规则 
		{regex("<int>"),"(\\d+)"},{regex("<str>"),"(\\w+)"},{regex("<path>"),"(.+)"}
	};
	while(n--){
		cin>>p>>r;
		for(auto &i:trans){
			p=regex_replace(p,i.first,i.second);
		rules.push_back({r,regex(p)});
		}
	}
	smatch result; 
	while(m--){
		cin>>p;
		for(auto &i:rules)
			if(regex_match(p,result,i.second)){
				cout<<i.first.c_str();
				for(auto i=1;i<=result.size();++i){
					p=result.str(i).c_str();
					if(p!="" && isStringDigit(p))
						cout<<' '<<stoi(p);
					else
						cout<<' '<<p.c_str(); 
				}
				puts("");
				goto loop; 
			}
		puts("404");
		loop:;
	}
	return 0;
}



3.提交结果

在这里插入图片描述

总结

1.解释

  1. vector<pair<string,regex>> rules;

这行代码定义了一个名为rules的vector变量,其中每个元素都是一个pair<string,regex>类型的对象。vector是一个动态数组,可以在运行时动态地增加或删除元素。pair<string,regex>表示一个包含两个元素的对象,第一个元素是一个string类型,第二个元素是一个regex类型。

在这个程序中,rules用来存储一组URL规则,每条规则都映射为一个规则名(字符串)和一个对应的正则表达式(regex)。程序会读入这些规则并将它们存储在rules中,然后对于每个输入的URL地址,程序会逐一匹配每条规则,如果匹配成功,则输出对应的规则名和匹配到的元组。

在上面的例子中,程序读入了5条URL规则,分别为:

/articles/2003/ special_case_2003
/articles/<int>/ year_archive
/articles/<int>/<int>/ month_archive
/articles/<int>/<int>/<str>/ article_detail
/static/<path> static_serve

程序会使用转换规则将这些URL规则转换为对应的正则表达式,并将转换后的正则表达式和规则名一起存储在rules中。

经过转换后,rules中的内容如下:

rules.push_back({regex("/articles/2003/"), "special_case_2003"});
rules.push_back({regex("/articles/(\\d+)/"), "year_archive"});
rules.push_back({regex("/articles/(\\d+)/(\\d+)/"), "month_archive"});
rules.push_back({regex("/articles/(\\d+)/(\\d+)/(\\w+)/"), "article_detail"});
rules.push_back({regex("/static/(.+)"), "static_serve"});

这就是在上面的例子中,经过转换后存储在rules中的内容。

  1. 正则表达式
vector<pair<regex,string>> trans={
	{regex("<int>"),"(\\d+)"},{regex("<str>"),"(\\w+)"},{regex("<path>"),"(.+)"}
};

这行代码中的几个正则表达式分别表示:

(\d+):匹配一个或多个数字字符。\d表示一个数字字符,+表示匹配一个或多个。
(\w+):匹配一个或多个字母、数字或下划线字符。\w表示一个字母、数字或下划线字符,+表示匹配一个或多个。
(.+):匹配一个或多个任意字符。.表示任意字符,+表示匹配一个或多个。
这些正则表达式用来将输入的URL规则转换为对应的正则表达式,以便程序能够使用正则表达式匹配来判断输入的URL地址是否符合规则。

在这个程序中,trans用来存储一组转换规则,每条规则都映射为一个正则表达式(regex)和一个对应的字符串(string)。程序会读入一组URL规则,然后使用这些转换规则将每条URL规则转换为对应的正则表达式。例如,对于URL规则中的部分,程序会使用正则表达式(\d+)来替换它。

这些转换规则用来将输入的URL规则转换为对应的正则表达式,以便程序能够使用正则表达式匹配来判断输入的URL地址是否符合规则。

  1. 举例子

例如,对于第一条URL规则/articles/2003/ special_case_2003,程序会将其拆分为规则名special_case_2003和规则内容/articles/2003/。

然后,程序会使用另一个for循环遍历trans中的每条转换规则。对于每条转换规则,程序使用regex_replace函数将URL规则内容中与转换规则的第一个元素(正则表达式)匹配的部分替换为转换规则的第二个元素(字符串)。

例如,在上面的例子中,由于URL规则内容中没有任何部分与转换规则匹配,因此经过一系列的替换操作后,URL规则内容仍然保持不变。

最后,程序使用push_back函数将转换后的正则表达式和规则名一起存储在rules中。这样,当程序需要判断输入的URL地址是否符合规则时,就可以直接使用这些存储在rules中的正则表达式进行匹配。

a.
例如,在上面的例子中,经过转换后,第一条URL规则被存储在rules中为:

rules.push_back({regex(“/articles/2003/”), “special_case_2003”});
这就是程序如何使用转换规则将这些URL规则转换为对应的正则表达式,并将转换后的正则表达式和规则名存储在rules中的过程。

对于这个例子,程序会将URL规则/articles// year_archive拆分为规则名year_archive和规则内容/articles//。

然后,程序会使用一个for循环遍历每条转换规则。对于每条转换规则,程序使用regex_replace函数将URL规则内容中与转换规则的第一个元素(正则表达式)匹配的部分替换为转换规则的第二个元素(字符串)。

b.
对于/articles/<int>/ year_archive
在这个例子中,由于URL规则内容中出现了字符串,因此它与第一条转换规则匹配。所以程序会使用regex_replace函数将URL规则内容中的字符串替换为(\d+)。

经过一系列的替换操作后,URL规则内容变为了/articles/(\d+)/。

最后,程序使用push_back函数将转换后的正则表达式和规则名一起存储在rules中。这样,当程序需要判断输入的URL地址是否符合规则时,就可以直接使用这些存储在rules中的正则表达式进行匹配。

例如,在上面的例子中,经过转换后,第二条URL规则被存储在rules中为:

rules.push_back({regex(“/articles/(\d+)/”), “year_archive”});
这就是程序如何使用转换规则将这条URL规则转换为对应的正则表达式,并将转换后的正则表达式和规则名存储在rules中的过程。

  1. 匹配过程解释

smatch result;

定义了一个名为result的smatch对象。smatch是一个标准库类型,它用于存储正则表达式匹配的结果。在这个程序中,result对象用于存储regex_match函数匹配输入URL时的结果。

当使用regex_match函数检查输入URL是否与规则的正则表达式匹配时,如果匹配成功,函数会将匹配结果存储在result对象中。然后程序可以通过访问result对象来获取匹配结果中的子匹配。

这段代码是程序的主要部分,它负责读入输入URL并将它们与规则进行匹配。下面是对这段代码中各个函数和变量的解释:

m:输入URL的数量。
cin>>p:读入一个输入URL。
for(auto &i:rules):遍历所有规则。
regex_match(p,result,i.second):使用正则表达式匹配函数regex_match检查输入URLp是否与当前规则的正则表达式i.second匹配。如果匹配,函数返回true,并将匹配结果存储在result中。
cout<<i.first.c_str():如果URL与当前规则匹配,则输出该规则对应的名称i.first。
for(auto i=1;i<=result.size();++i):遍历匹配结果中的所有子匹配。
p=result.str(i).c_str():获取第i个子匹配的字符串。
isStringDigit§:调用自定义函数isStringDigit检查子匹配字符串是否为整数。
cout<<’ ‘<<stoi§:如果子匹配字符串为整数,则使用函数stoi将其转换为整数并输出。
cout<<’ '<<p.c_str():如果子匹配字符串不是整数,则直接输出该字符串。
puts(“”):在每个URL的输出后换行。
goto loop:如果URL与任意一条规则匹配,则跳过剩余的规则并直接处理下一个URL。
puts(“404”):如果URL与任何一条规则都不匹配,则输出"404"。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值