// NEW CODE
#include "jpcre2.hpp"
#include <iostream>
typedef
jpcre2::select<
char
> jp;
int
main() {
// SAMPLE CODE
//Check if string matches the pattern
/*
* The following uses a temporary Regex object.
*/
std::cout <<
"\n\n"
<<
"[[[ DEBUG ]]] BEFORE MATCH 1"
<<
"\n\n"
;
if
(jp::Regex(
"(\\d)|(\\w)"
).match(
"I am the subject"
)) {
std::cout <<
"\nmatched"
;
}
std::cout <<
"\n\n"
<<
"[[[ DEBUG ]]] AFTER MATCH 1"
<<
"\n\n"
;
/*
* Using the modifier S (i.e jpcre2::JIT_COMPILE) with temporary object may or may not give you
* any performance boost (depends on the complexity of the pattern). The more complex
* the pattern gets, the more sense the S modifier makes.
*/
//If you want to match all and get the match count, use the action modifier 'g':
std::cout <<
"\n\n"
<<
"[[[ DEBUG ]]] BEFORE MATCH 2"
<<
"\n\n"
;
std::cout <<
"\n"
<< jp::Regex(
"(\\d)|(\\w)"
,
"m"
).match(
"I am the subject"
,
"g"
);
std::cout <<
"\n\n"
<<
"[[[ DEBUG ]]] AFTER MATCH 2"
<<
"\n\n"
;
size_t
count;
/*
* Modifiers passed to the Regex constructor or with compile() function are compile modifiers
* Modifiers passed with the match() or replace() functions are action modifiers
*/
// Substrings/Captured groups:
/*
* *** Getting captured groups/substring ***
*
* captured groups or substrings are stored in maps/vectors for each match,
* and each match is stored in a vector.
* Thus captured groups are in a vector of maps/vectors.
*
* PCRE2 provides two types of substrings:
* 1. numbered (indexed) substring
* 2. named substring
*
* For the above two, we have two vectors respectively:
* 1. jp::VecNum (Corresponding vector: jp::NumSub)
* 2. jp::VecNas (Corresponding map: jp::MapNas)
*
* Another additional vector is available to get the substring position/number
* for a particular captured group by name. It's a vector of name to number maps
* * jp::VecNtN (Corresponding map: jp:MapNtN)
*/
// ***** Get numbered substring ***** ///
jp::VecNum vec_num;
jp::RegexMatch rm;
jp::Regex re(
"(\\w+)\\s*(\\d+)"
,
"m"
);
count =
jp::RegexMatch(&re).setSubject(
"I am 23, I am digits 10"
)
.setModifier(
"g"
)
.setNumberedSubstringVector(&vec_num)
.match();
/*
* count (the return value) is guaranteed to give you the correct number of matches,
* while vec_num.size() may give you wrong result if any match result
* was failed to be inserted in the vector. This should not happen
* i.e count and vec_num.size() should always be equal.
*/
std::cout<<
"\nNumber of matches: "
<<count
/* or vec_num.size()*/
;
//Now vec_num is populated with numbered substrings for each match
//The size of vec_num is the total match count
//vec_num[0] is the first match
//The type of vec_num[0] is jp::NumSub
std::cout<<
"\nTotal match of first match: "
<<vec_num[0][0];
std::cout<<
"\nCaptured group 1 of first match: "
<<vec_num[0][1];
std::cout<<
"\nCaptured group 2 of first match: "
<<vec_num[0][2];
//captured group 3 doesn't exist, (with operator [] it's a segfault)
//std::cout<<"\nCaptured group 3 of first match: "<<vec_num[0][3];
//Using at() will throw std::out_of_range exception
//~ try {
//~ std::cout<<"\nCaptured group 3 of first match: "<<vec_num[0].at(3);
//~ } catch (const std::out_of_range& e) {
//~ std::cerr<<"\n"<<e.what();
//~ }
//There were two matches found (vec_num.size() == 2) in the above example
std::cout<<
"\nTotal match of second match: "
<<vec_num[1][0];
//Total match (group 0) from second match
std::cout<<
"\nCaptured group 1 of second match: "
<<vec_num[1][1];
//captured group 1 from second match
std::cout<<
"\nCaptured group 2 of second match: "
<<vec_num[1][2];
//captured group 2 from second match
// ***** Get named substring ***** //
jp::VecNas vec_nas;
jp::VecNtN vec_ntn;
// We will get name to number map vector too
re.compile(
"(?<word>\\w+)\\s*(?<digit>\\d+)"
,
"m"
);
count =
jp::RegexMatch(&re).setSubject(
"I am 23, I am digits 10"
)
.setModifier(
"g"
)
//.setNumberedSubstringVector(vec_num) // We don't need it in this example
.setNamedSubstringVector(&vec_nas)
.setNameToNumberMapVector(&vec_ntn)
// Additional (name to number maps)
.match();
std::cout<<
"\nNumber of matches: "
<<vec_nas.size()
/* or count */
;
//Now vec_nas is populated with named substrings for each match
//The size of vec_nas is the total match count
//vec_nas[0] is the first match
//The type of vec_nas[0] is jp::MapNas
std::cout<<
"\nCaptured group (word) of first match: "
<<vec_nas[0][
"word"
];
std::cout<<
"\nCaptured group (digit) of first match: "
<<vec_nas[0][
"digit"
];
//Trying to access a non-existence named substirng with [] operator will give you empty string
//If the existence of a substring is important, use the std::map::find() or std::map::at()
//(>=C++11) function to access map elements.
/* //>=C++11
try{
///This will throw exception because the substring name 'name' doesn't exist
std::cout<<"\nCaptured group (name) of first match: "<<vec_nas[0].at("name");
} catch(const std::logic_error& e){
std::cerr<<"\nCaptured group (name) doesn't exist";
}*/
//There were two matches found (vec_nas.size() == 2) in the above example
std::cout<<
"\nCaptured group (word) of second match: "
<<vec_nas[1][
"word"
];
std::cout<<
"\nCaptured group (digit) of second match: "
<<vec_nas[1][
"digit"
];
//Get the position (number) of a captured group name (that was found in match)
std::cout<<
"\nPosition of captured group (word) in first match: "
<<vec_ntn[0][
"word"
];
std::cout<<
"\nPosition of captured group (digit) in first match: "
<<vec_ntn[0][
"digit"
];
/*
* Replacement Examples
* Replace pattern in a string with a replacement string
*
* The Regex::replace() function can take a subject and replacement string as argument.
*
* You can also pass the subject with setSubject() function in method chain,
* replacement string with setReplaceWith() function in method chain, etc ...
* A call to RegexReplace::replace() in the method chain will return the resultant string
*/
std::cout<<
"\n"
<<
//replace first occurrence of a digit with @
jp::Regex(
"\\d"
).replace(
"I am the subject string 44"
,
"@"
);
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]+)$"
)
.replace(
"I am the subject\tTo be swapped according to tab"
,
"$2 $1"
);
//Doing the above with method chain:
re.compile(
"^([^\t]+)\t([^\t]+)$"
);
jp::RegexReplace(&re).setSubject(
"I am the subject\tTo be swapped according to tab"
)
.setReplaceWith(
"$2 $1"
)
.replace();
// NEW CODE
}