• C++正则表达式例子


    给了策划配置公式的地方,需要将策划配置的公式文本转化为可执行的脚本代码:
    比如:self->mHp*2+target->2mMp*GetHit()+ self_mon->4mDan/1000 ==> self:lf_mHp(0)*2+dst:lf_mMp(2)*GetHit()+ src:lf_mDan(4)/1000

    意思就是
    1 指针变量凡是含有self的都变为src,target的都替换为dst
    2 调用的属性前面的系数要提取出来
    3 属性可能是多种多样的,所以提取方法不能写死。

    当时时间紧急,对正则表达式也不熟,按照字符串分割的方法实现了。

    代码如下:

      1 void TestFormula(std::string& for_text)
      2 {
      3     using std::string;
      4     using std::vector;
      5     string::size_type pos = 0;
      6     string searchStr = "->";
      7     string replaceStr = "#";
      8 
      9     if (for_text.find(searchStr) == string::npos)
     10     {
     11         return;
     12     }
     13 
     14     while ( (pos = for_text.find(searchStr, pos)) != string::npos)
     15     {
     16         if ((for_text.size() >= pos + 2 && for_text[pos + 2] == 'm') || (for_text.size() >= pos + 3 && for_text[pos + 3] == 'm' && for_text[pos + 2] >= '0' && for_text[pos + 2] <= '9'))
     17         {
     18             for_text.replace(pos, searchStr.size(), replaceStr);
     19         }
     20         pos++;
     21     }
     22         
     23     vector<string> lVector;
     24     vector<string> rVector;
     25     int lastSplitIdx = 0;
     26     string lastText("");
     27     for (string::size_type i = 0; i < for_text.size(); i++)
     28     {
     29         if (for_text[i] == '+' || for_text[i] == '-' || for_text[i] == '*' || for_text[i] == '/'
     30             || for_text[i] == '#' || for_text[i] == '(' || for_text[i] == ')' || for_text[i] == ',')
     31         {
     32             if (for_text[i] == '#')
     33             {
     34                 lastText = for_text.substr(lastSplitIdx, i - lastSplitIdx);
     35             }
     36             else 
     37             {
     38                 if (lastText.size() > 0)
     39                 {
     40                     lVector.push_back(lastText);
     41                     rVector.push_back(for_text.substr(lastSplitIdx, i - lastSplitIdx));
     42                 }
     43                 lastText = "";
     44             }
     45             lastSplitIdx = i + 1;
     46         }
     47     }
     48     if (lastSplitIdx != for_text.size())
     49     {
     50         if (lastText.size() > 0)
     51         {
     52             lVector.push_back(lastText);
     53             rVector.push_back(for_text.substr(lastSplitIdx, lastText.size() - lastSplitIdx));
     54         }
     55     }
     56 
     57     if (lVector.size() == 0 || rVector.size() == 0 || lVector.size() != rVector.size())
     58     {
     59         return;
     60     }
     61 
     62     pos = 0;
     63     int parseIdx = 0;
     64     while ( ( pos = for_text.find(replaceStr, pos)) != string::npos)
     65     {
     66         string leftStr = lVector.at(parseIdx);
     67         string rightStr = rVector.at(parseIdx);
     68         string oldStr = leftStr + replaceStr + rightStr;
     69         string category = rightStr.substr(0, 1);
     70         string ower = leftStr;
     71         if (category == "0" || category == "1" || category == "2" || category == "3" || category == "4")
     72         {
     73             rightStr = rightStr.substr(1, rightStr.size());
     74         }
     75         else
     76         {
     77             category = "0";
     78         }
     79         if (leftStr.find("self", 0) != string::npos)
     80         {
     81             ower = "src";
     82         }
     83         else if (leftStr.find("target", 0) != string::npos)
     84         {
     85             ower = "dst";
     86         }
     87         string newStr = ower + ":lf_" + rightStr + "(" + category + ")";
     88         for_text.replace(pos - leftStr.size(), oldStr.size(), newStr);
     89         parseIdx++;
     90         pos++;
     91     }
     92 }
     93 int main()
     94 {
     95     std::string text("self->mHp*2+target->2mMp*GetHit()+self_mon->4mDan/1000");
     96     std::cout << text.c_str() << std::endl;
     97     TestFormula(text);
     98     std::cout<<text.c_str()<<std::endl;
     99 
    100     return 0;
    101 }    

    运行结果:

    颇费周折有木有~~~,还有很多临界状态需要检查,一不留神可能就踩到坑里了。

    索性,看了看正则表达式,发现非常好用。代码少很多,结果一模一样。

     1 void TestFormulaRegex(std::string& for_text)
     2 {
     3     using std::string;
     4     std::regex pat("([A-Za-z_]+)->([0-4]*)(m[A-Za-z]+)");
     5     string::const_iterator startPos = for_text.begin();
     6     string::const_iterator endPos = for_text.end();
     7     std::smatch mat;
     8     while (std::regex_search(startPos, endPos, mat, pat))
     9     {
    10         string object(mat[1].first, mat[1].second);
    11         string category(mat[2].first, mat[2].second);
    12         string attrName(mat[3].first, mat[3].second);
    13         if (category.compare("") == 0)
    14         {
    15             category = "0";
    16         }
    17         if (object.find("self", 0) != string::npos)
    18         {
    19             object = "src";
    20         }
    21         else if (object.find("target", 0) != string::npos)
    22         {
    23             object = "dst";
    24         }
    25         string replaceStr(object + ":lf_" + attrName + "(" + category + ")");
    26         for_text.replace(mat[0].first, mat[0].second, replaceStr);
    27         startPos = for_text.begin();
    28         endPos = for_text.end();
    29     }
    30 }
  • 相关阅读:
    chrome浏览器中安装以及使用Elasticsearch head 插件
    windows10 升级并安装配置 jmeter5.3
    linux下部署Elasticsearch6.8.1版本的集群
    【Rollo的Python之路】Python 爬虫系统学习 (八) logging模块的使用
    【Rollo的Python之路】Python 爬虫系统学习 (七) Scrapy初识
    【Rollo的Python之路】Python 爬虫系统学习 (六) Selenium 模拟登录
    【Rollo的Python之路】Python 爬虫系统学习 (五) Selenium
    【Rollo的Python之路】Python 爬虫系统学习 (四) XPath学习
    【Rollo的Python之路】Python 爬虫系统学习 (三)
    【Rollo的Python之路】Python sys argv[] 函数用法笔记
  • 原文地址:https://www.cnblogs.com/lan0725/p/6655803.html
Copyright © 2020-2023  润新知