首页 > 代码库 > C++正则表达式例子

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 }

 

C++正则表达式例子