这题可以用正则表达式做会特别简单,用regex_replace()函数,
可以很方便和快速的把行内的强调和超链接替换成html格式。
判断是否下一个区块则用flag标记,flag为1表示空行,为0表示区块。
因为段落和列表没法判断区块尾,所以用tap来标记上一个区块是什么类型的区块,在出现空行时则根据上一个区块的类型补足区块尾
C++ 代码
//3.Markdown - 正则表达式 _会极其简单
#include<bits/stdc++.h>
using namespace std;
string patt1("#+");
string patt2("_(.+?)_");//强调
string patt3("\\[(.+?)\\]\\((.+?)\\)");//超链接
regex r1(patt1);
regex r2(patt2);
regex r3(patt3);
string deal(string s){//处理行内字符串
while(s[0] == ' ') s.erase(s.begin());
s = regex_replace(s, r2, "<em>$1</em>");
s = regex_replace(s, r3, "<a href=\"$2\">$1</a>");
return s;
}
int main(){
string line;
int tap = 0, flag = 1;
while(getline(cin, line)){
if(line == ""){//空行时对上一区块尾处理
if(flag == 0 && tap == 2){
cout << "</ul>" << endl;
}
else if(flag == 0 && tap == 3) cout << "</p>" << endl;
flag = 1;
}
else{
stringstream ssin(line);
string s;
ssin >> s;
if(regex_match(s,r1)){//1是标题
int a = s.size();
getline(ssin, s);
s = deal(s);
cout << "<h" << a << ">" << s << "</h" << a << ">" << endl;
tap = 1;
}
else if(s == "*"){//2是列表
if(flag){
cout << "<ul>" << endl;
}
getline(ssin, s);
s = deal(s);
cout << "<li>" << s << "</li>" << endl;
tap = 2;
}
else{//3是段落
if(flag){
cout << "<p>";
}
else cout << endl;
string s2;
getline(ssin, s2);
s = s + s2;
cout << deal(s);
tap = 3;
}
flag = 0;
}
}
//最后再补上区块尾
if(flag == 0 && tap == 2) cout << "</ul>" << endl;
else if(flag == 0 && tap == 3) cout << "</p>" << endl;
return 0;
}
orz