关于C++中正则表达式的知识,请参考这两篇博客,我也是看的这两篇博客就大致清楚怎么用了。
https://blog.csdn.net/weixin_42416780/article/details/89791826 这个对方法的介绍比较详细。
https://blog.csdn.net/philpanic9/article/details/88141305 这个可以只看开头那个表格,那个表格很好懂。
关于捕获组的问题:https://www.runoob.com/java/java-regular-expressions.html,可以看这里面的捕获组,虽然这篇文章讲的是java的捕获组,但是跟c++相同。
这道题用正则表达式很好做,这个思路来自于这篇文章:https://blog.csdn.net/richenyunqi/article/details/85260248
试题编号: | 201803-3 |
试题名称: | URL映射 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 URL 映射是诸如 Django、Ruby on Rails 等网页框架 (web frameworks) 的一个重要组件。对于从浏览器发来的 HTTP 请求,URL 映射模块会解析请求中的 URL 地址,并将其分派给相应的处理代码。现在,请你来实现一个简单的 URL 映射功能。 输入格式 输入第一行是两个正整数 n 和 m,分别表示 URL 映射的规则条数和待处理的 URL 地址个数,中间用一个空格字符分隔。 输出格式 输入共 m 行,第 i 行表示 qi 的匹配结果。如果匹配成功,设匹配了规则 pj ,则输出对应的 rj。同时,如果规则中有参数,则在同一行内依次输出匹配后的参数。注意整数参数输出时要把前导零去掉。相邻两项之间用一个空格字符分隔。如果匹配失败,则输出 404。 样例输入 5 4 样例输出 year_archive 2004 样例说明 对于第 1 个地址 /articles/2004/,无法匹配第 1 条规则,可以匹配第 2 条规则,参数为 2004。 数据规模和约定 1 ≤ n ≤ 100,1 ≤ m ≤ 100。 |
#include<iostream>
#include<regex>
#include<algorithm>
#include<string>
#include<sstream>
#include<vector>
using namespace std;
/*
** 规则
** rulename:指的是规则的名字
** rulepattern:规则对应的正则表达式
** 比如对这个url映射规则来说:/articles/<int>/ year_archive
** rulename : year_archive
** rulepattern : /articles/([0-9]+)/
*/
struct Rule{
string rulename;
regex rulepattern;
Rule(string name,regex pattern){
this->rulename = name;
this->rulepattern = pattern;
}
};
/*
** url映射规则里面的参数和正则表达式的对应关系
** 比如这个url映射规则:/articles/<int>/<int>/<str>/ article_detail
** 参数:<int> 和 <str>
** 参数对应的正则表达式分别为: ([0-9]+) 和 ([a-zA-Z0-9-_./]+)
*/
struct Transfer{
regex from;
string to;
};
vector<Rule> rules; //存放正则表达式组成的映射规则
vector<Transfer> transfer = {
{regex("<int>"),"([0-9]+)"},
{regex("<str>"),"([a-zA-Z0-9-_.]+)"},
{regex("<path>"),"([a-zA-Z0-9-_./]+)"}
}; //存放参数和正则表达式的对应关系
/*
** 判断参数是不是数字,如果是的话,要去掉前导0。
*/
bool myIsDigit(string input){
for(int i=0;i<input.length();i++){
if(!isdigit(input[i])){
return false;
}
}
return true;
}
/*
** string转int,也是去掉前导0的过程。
*/
int toInt(string str){
istringstream input(str);
int ans;
input>>ans;
return ans;
}
int main(){
int n,m;
string pattern,name;
string url;
cin>>n>>m;
while(n--){
cin>>pattern>>name;
/*
** 把带有参数的url映射规则,转换为带有正则表达式的url映射规则
** 比如把这个带有参数的映射规则:/articles/<int>/<int>/<str>/
** 转换为: /articles/([0-9]+)/([0-9]+)/([a-zA-Z0-9-_.]+)/
*/
for(int i=0;i<transfer.size();i++){
pattern = regex_replace(pattern,transfer[i].from,transfer[i].to);
}
rules.push_back(Rule(name,regex(pattern)));
}
while(m--){
cin>>url;
/*
** 存放匹配成功后的捕获组。
*/
smatch group;
bool flag = false;
/*
** 用映射规则依次进行匹配
*/
for(int i=0;i<rules.size();i++){
if(regex_match(url,group,rules[i].rulepattern)){ //如果匹配成功
cout<<rules[i].rulename;
for(int i=1;i<group.size();i++){ //遍历每个匹配到的参数
if(myIsDigit(group[i])){ //参数是不是数字
cout<<" "<<toInt(group[i]);
}else{
cout<<" "<<group[i];
}
}
cout<<endl;
flag = true;
break;
}
}
if(!flag){
cout<<"404"<<endl;
}
}
return 0;
}