If you don't mind using a wrapper, here's mine: JPCRE2
You need to select the main character type ( char , wchar_t , char16_t , char32_t ) according to the string classes that you will use (respectively std::string , std::wstring , std::u16string , std::u32string ):
typedef jpcre2::select<char> jp; //Selecting char as the basic character type will require //8 bit PCRE2 library where char is 8 bit, //or 16 bit PCRE2 library where char is 16 bit, //or 32 bit PCRE2 library where char is 32 bit. //If char is not 8, 16 or 32 bit, it a compile error.
Matching examples:
Check if the string matches the pattern:
if(jp::Regex("(\\d)|(\\w)").match("I am the subject")) std::cout<<"\nmatched"; else std::cout<<"\nno match";
Match everything and get a match:
size_t count = jp::Regex("(\\d)|(\\w)","mi").match("I am the subject", "g"); // 'm' modifier enables multi-line mode for the regex // 'i' modifier makes the regex case insensitive // 'g' modifier enables global matching
Get numbered substrings / captured groups:
jp::VecNum vec_num; count = jp::Regex("(\\w+)\\s*(\\d+)","im").initMatch() .setSubject("I am 23, I am digits 10") .setModifier("g") .setNumberedSubstringVector(&vec_num) .match(); std::cout<<"\nTotal match of first match: "<<vec_num[0][0]; std::cout<<"\nCaptrued group 1 of first match: "<<vec_num[0][1]; std::cout<<"\nCaptrued group 2 of first match: "<<vec_num[0][2]; std::cout<<"\nTotal match of second match: "<<vec_num[1][0]; std::cout<<"\nCaptrued group 1 of second match: "<<vec_num[1][1]; std::cout<<"\nCaptrued group 2 of second match: "<<vec_num[1][2];
Get substrings / captured groups:
jp::VecNas vec_nas; count = jp::Regex("(?<word>\\w+)\\s*(?<digit>\\d+)","m") .initMatch() .setSubject("I am 23, I am digits 10") .setModifier("g") .setNamedSubstringVector(&vec_nas) .match(); std::cout<<"\nCaptured group (word) of first match: "<<vec_nas[0]["word"]; std::cout<<"\nCaptured group (digit) of first match: "<<vec_nas[0]["digit"]; std::cout<<"\nCaptured group (word) of second match: "<<vec_nas[1]["word"]; std::cout<<"\nCaptured group (digit) of second match: "<<vec_nas[1]["digit"];
Iterate over all matches and substrings:
//Iterating through numbered substring for(size_t i=0;i<vec_num.size();++i){ //i=0 is the first match found, i=1 is the second and so forth for(size_t j=0;j<vec_num[i].size();++j){ //j=0 is the capture group 0 ie the total match //j=1 is the capture group 1 and so forth. std::cout<<"\n\t("<<j<<"): "<<vec_num[i][j]<<"\n"; } }
Replace / replace examples:
std::cout<<"\n"<< ///replace all occurrences of a digit with @ jp::Regex("\\d").replace("I am the subject string 44", "@", "g"); ///swap two parts of a string std::cout<<"\n"<< jp::Regex("^([^\t]+)\t([^\t]+)$") .initReplace() .setSubject("I am the subject\tTo be swapped according to tab") .setReplaceWith("$2 $1") .replace();
Replace with conformity assessment:
jp::String callback1(const jp::NumSub& m, void*, void*){ return "("+m[0]+")"; //m[0] is capture group 0, ie total match (in each match) } int main(){ jp::Regex re("(?<total>\\w+)", "n"); jp::RegexReplace rr(&re); String s3 = "I am ঋ আা a string 879879 fdsjkll ১ ২ ৩ ৪ অ আ ক খ গ ঘ আমার সোনার বাংলা"; rr.setSubject(s3) .setPcre2Option(PCRE2_SUBSTITUTE_GLOBAL); std::cout<<"\n\n### 1\n"<< rr.nreplace(jp::MatchEvaluator(callback1)); //nreplace() treats the returned string from the callback as literal, //while replace() will process the returned string //with pcre2_substitute() #if __cplusplus >= 201103L //example with lambda std::cout<<"\n\n### Lambda\n"<< rr.nreplace( jp::MatchEvaluator( [](const jp::NumSub& m1, const jp::MapNas& m2, void*){ return "("+m1[0]+"/"+m2.at("total")+")"; } )); #endif return 0; }
You can read the full documentation here .