CCF认证 201703-3Markdown——31行代码(正则表达式)

欢迎访问我的CCF认证考试题解目录哦 https://blog.csdn.net/richenyunqi/article/details/83385502

题目描述

CCF认证 201703-3Markdown——31行代码(正则表达式)_第1张图片

算法设计

每两个区块之间用一个或多个空行分隔,可以先逐行读取全部的输入字符串,遇到一个空行就代表一个区块已读取完毕,将这个区块中的所有字符串放到一个vector类型的变量中,然后将每一个读取的区块放到vector>markdown变量中。然后针对每一个区块内的字符串进行操作。
接下来就是对字符串的查找替换操作,这一过程可以使用正则表达式来完成。关于正则表达式可以参考教程正则表达式 – 语法。这里只详细解释一下用到的正则表达式。

  • 对于正则表达式^\\* +(.*),转换为字符串
  • $1
    • ^表示匹配输入字符串的开始位置
    • \\*表示字符*
    • +表示一个或多个空格字符
    • .*表示任意个非\n字符
    • ()表示标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。
      所以正则表达式^\\* +(.*)就表示了字符*开始+一个或多个空格+任意字符串形式的字符串,对应着题目中无序列表。
  • 对于正则表达式_([^_]+)_
    • _表示字符_
    • [^_]+表示一个或多个非_字符

所以正则表达式_([^_]+)_对应着题目中强调语法。

  • 对于正则表达式\\[([^\\]]+)\\]\\(([^\\)]+)\\)
    • \\[表示字符[
    • [^\\]]+表示一个或多个非]字符
    • \\]\\(\\)表示字符]()
    • ([^\\)]+表示一个或多个非)字符

所以正则表达式\\[([^\\]]+)\\]\\(([^\\)]+)\\)对应着题目中超级链接语法。
其他正则表达式与之类似。具体实现可见代码。

C++代码

#include
using namespace std;
int main(){
    vector<pair<regex,string>>trans={
        {regex("^\\* +(.*)"),"
  • $1
  • "
    },//无序列表 {regex("_([^_]+)_"),"$1"},//强调 {regex("\\[([^\\]]+)\\]\\(([^\\)]+)\\)"),"$1"}//超链接 }; for(int i=1;i<=6;++i)//6中等级的标题 trans.push_back({regex("^"+string(i,'#')+" +(.*)"),"+to_string(i)+">$1+to_string(i)+">"}); vector<vector<string>>markdown(1);//按区块存储所有字符串 string s=""; while(getline(cin,s))//读取markdown文本 if(s==""){//遇到空行 markdown.push_back({});//新增区块 }else markdown.back().push_back(s); for(auto&i:markdown){//遍历所有区块 if(i.empty())//区块为空,不进行任何操作 continue; int type=i[0][0]=='*'?0:i[0][0]=='#'?1:2;//type为0/1/2分别表示无序列表、标题、段落 printf("%s",type==0?"
      \n":type==2?"

      ":"");//输出

        for(int j=0;j<i.size();++j){//遍历区块中所有字符串 for(auto&k:trans)//遍历所有正则表达式进行替换 i[j]=regex_replace(i[j],k.first,k.second); printf("%s%s",i[j].c_str(),j==i.size()-1?"":"\n");//输出该字符串 } puts(type==0?"\n

      "
      :type==2?"

      "
      :"");//输出

    } return 0; }

    你可能感兴趣的:(CCF)