zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    事务传播机制,搞懂。
    洛谷 P1553 数字反转(升级版) 题解
    洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is Here 题解
    洛谷 P1055 ISBN号码 题解
    洛谷 P2141 珠心算测验 题解
    洛谷 P1047 校门外的树 题解
    洛谷 P1980 计数问题 题解
    洛谷 P1008 三连击 题解
    HDU 1013 题解
    HDU 1012 题解
  • 原文地址:https://www.cnblogs.com/lan0725/p/6655803.html
Copyright © 2011-2022 走看看