![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Understanding Marked Sub-Expressions and CapturesBoost , Boost.Regex 5.1.2 , Boost.Regex 5.1.2
|
Подвыражение |
Текст найден |
---|---|
$ |
"@" |
$& |
"abc def" |
$1 |
"abc" |
$2 |
"def" |
$ |
"--" |
В Росте. Все они доступны через класс match_results
, который заполняется при вызове одного из алгоритмов соответствия регулярных выражений (regex_search
, regex_match
или regex_iterator
). Так дано:
boost::match_results<IteratorType> m;
Перл и буст. Эквивалентами Regex являются:
Перл |
Повышаю. Регей |
---|---|
$ |
|
$& |
|
$n |
|
$ |
|
В Росте. Каждый подэкспрессионный матч представлен объектом sub_match
, это в основном просто пара итераторов, обозначающих начальное и конечное положение подэкспрессионного матча, но есть некоторые дополнительные операторы, предоставленные таким образом, что объекты типа sub_match
ведут себя очень похоже на std::basic_string
: например, они неявно конвертируемы в basic_string
, их можно сравнить со строкой, добавить к строке или выпустить на выходной поток.
При обнаружении регулярного совпадения выражений нет необходимости в том, чтобы все отмеченные субвыражения участвовали в матче, например, выражение:
(abc)|(def)
это может быть как $1, так и $2, но не одновременно. В Росте. Regex можно определить, какие подэкспрессии совпадают, получив доступ к sub_match::matched
элементу данных.
Когда отмеченное подвыражение повторяется, то подвыражение «захватывается» несколько раз, однако обычно доступен только окончательный захват, например, если
(?:(\w+)\W+)+
противопоставляется
one fine day
Тогда $1 будет содержать строку "день", а все предыдущие захваты будут забыты.
Тем не менее, буст. Regex имеет экспериментальную функцию, которая позволяет сохранить всю информацию о захвате - к ней можно получить доступ либо через функцию члена match_results::captures
, либо через функцию члена sub_match::captures
. Эти функции возвращают контейнер, который содержит последовательность всех захватов, полученных во время согласования регулярных выражений. Следующий пример программы показывает, как эта информация может быть использована:
#include <boost/regex.hpp> #include <iostream> void print_captures(const std::string& regx, const std::string& text) { boost::regex e(regx); boost::smatch what; std::cout << "Expression: \"" << regx << "\"\n"; std::cout << "Text: \"" << text << "\"\n"; if(boost::regex_match(text, what, e, boost::match_extra)) { unsigned i, j; std::cout << "** Match found **\n Sub-Expressions:\n"; for(i = 0; i < what.size(); ++i) std::cout << " $" << i << " = \"" << what[i] << "\"\n"; std::cout << " Captures:\n"; for(i = 0; i < what.size(); ++i) { std::cout << " $" << i << " = {"; for(j = 0; j < what.captures(i).size(); ++j) { if(j) std::cout << ", "; else std::cout << " "; std::cout << "\"" << what.captures(i)[j] << "\""; } std::cout << " }\n"; } } else { std::cout << "** No Match found **\n"; } } int main(int , char* []) { print_captures("(([[:lower:]]+)|([[:upper:]]+))+", "aBBcccDDDDDeeeeeeee"); print_captures("(.*)bar|(.*)bah", "abcbar"); print_captures("(.*)bar|(.*)bah", "abcbah"); print_captures("^(?:(\\w+)|(?>\\W+))*$", "now is the time for all good men to come to the aid of the party"); return 0; }
Который производит следующую продукцию:
Expression: "(([[:lower:]]+)|([[:upper:]]+))+" Text: "aBBcccDDDDDeeeeeeee" ** Match found ** Sub-Expressions: $0 = "aBBcccDDDDDeeeeeeee" $1 = "eeeeeeee" $2 = "eeeeeeee" $3 = "DDDDD" Captures: $0 = { "aBBcccDDDDDeeeeeeee" } $1 = { "a", "BB", "ccc", "DDDDD", "eeeeeeee" } $2 = { "a", "ccc", "eeeeeeee" } $3 = { "BB", "DDDDD" } Expression: "(.*)bar|(.*)bah" Text: "abcbar" ** Match found ** Sub-Expressions: $0 = "abcbar" $1 = "abc" $2 = "" Captures: $0 = { "abcbar" } $1 = { "abc" } $2 = { } Expression: "(.*)bar|(.*)bah" Text: "abcbah" ** Match found ** Sub-Expressions: $0 = "abcbah" $1 = "" $2 = "abc" Captures: $0 = { "abcbah" } $1 = { } $2 = { "abc" } Expression: "^(?:(\w+)|(?>\W+))*$" Text: "now is the time for all good men to come to the aid of the party" ** Match found ** Sub-Expressions: $0 = "now is the time for all good men to come to the aid of the party" $1 = "party" Captures: $0 = { "now is the time for all good men to come to the aid of the party" } $1 = { "now", "is", "the", "time", "for", "all", "good", "men", "to", "come", "to", "the", "aid", "of", "the", "party" }
К сожалению, включение этой функции влияет на производительность (даже если вы не используете ее), и гораздо большее влияние, если вы используете ее, поэтому для использования этой функции вам нужно:
Статья Understanding Marked Sub-Expressions and Captures раздела Boost.Regex 5.1.2 Boost.Regex 5.1.2 может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: Boost.Regex 5.1.2 ::
реклама |