Std::regex
lastmod 2018-08-17created 2015-10-2312 edits
The regular expressions library provides a class that represents Regular expressions, which are a kind of mini-language used to perform pattern matching within strings.
raw strings
- C++11 raw strings literals tutorial
- cppreference.com: string literal
- MSDN: String and character literals (C++)
You can store a RAW string as shown below.
The key point is that everything from R"( to )" is fixed syntax. If there are many parentheses and parsing gets confusing, use the syntax below.
Match check
Code that checks whether a path contains an absolute path on Windows is as follows.
bool hasAbsoluteOfWindows(std::string const & path) const {
if (std::regex_search(path, std::regex(R"(^[a-zA-Z]:)"))) {
return true;
}
return false;
}
Replace
Simple code that cleans up Path separators is as follows.
/**
* "O:\\\\Temp\\Directory/..\\.////\\\\/File.tmp\\/" -> "O:/Temp/Directory/.././File.tmp"
*/
static std::string cleanSeparator(std::string const & path) {
return std::regex_replace(path, std::regex(R"((\\|\/)(\\|\/)*)"), "/");
}
Example
#include <iostream>
#include <iterator>
#include <string>
#include <regex>
int main()
{
std::string s = "Some people, when confronted with a problem, think "
"\"I know, I'll use regular expressions.\" "
"Now they have two problems.";
std::regex self_regex("REGULAR EXPRESSIONS",
std::regex_constants::ECMAScript | std::regex_constants::icase);
if (std::regex_search(s, self_regex)) {
std::cout << "Text contains the phrase 'regular expressions'\n";
}
std::regex word_regex("(\\S+)");
auto words_begin =
std::sregex_iterator(s.begin(), s.end(), word_regex);
auto words_end = std::sregex_iterator();
std::cout << "Found "
<< std::distance(words_begin, words_end)
<< " words\n";
const int N = 6;
std::cout << "Words longer than " << N << " characters:\n";
for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
std::smatch match = *i;
std::string match_str = match.str();
if (match_str.size() > N) {
std::cout << " " << match_str << '\n';
}
}
std::regex long_word_regex("(\\w{7,})");
std::string new_s = std::regex_replace(s, long_word_regex, "[$&]");
std::cout << new_s << '\n';
}
Output:
Text contains the phrase 'regular expressions'
Found 19 words
Words longer than 6 characters:
people,
confronted
problem,
regular
expressions."
problems.
Some people, when [confronted] with a [problem], think
"I know, I'll use [regular] [expressions]." Now they have two [problems].
Troubleshooting
undefined reference to std::regex_iterator
On Linux-family systems, std::regex_iterator sometimes cannot be found, as shown below.
./libworld.a(Values.world.o): In function `world::Values::replaceEnvString(std::string&) const':
Values.cpp:(.text+0x795): undefined reference to `std::regex_iterator<__gnu_cxx::__normal_iterator<char const*, std::string>, char, std::regex_traits<char> >::regex_iterator()'
collect2: error: ld returned 1 exit status
The GNU C++ standard library supports <regex>, but not until version 4.9.0. (The headers were present in earlier versions, but were unusable.) The other compilers don't support it, as far as I can see. You can use a different library if you use an older GCC.
In other words, regex is supported starting with GCC 4.9.0.
See also
Favorite site
- cppreference.com: Regular expressions library
- Boost: Introduction to Regex++, a regular expression library
- TR1: regex