Этот сайт использует cookies. Продолжение работы с сайтом означает, что Вы согласны!
Просмотр вперед
Внутри круглых скобок могут быть расположены следующие конструкции:
(?=...)
— положительный просмотр вперед. Выведем все слова, после которых расположена запятая:
std::regex rgx("\\w+(?=[,])");
std::string str("text1, text2, text3 text4");
std::sregex_iterator istart(str.begin(), str.end(), rgx);
std::sregex_iterator iend;
while (istart != iend) {
std::cout << istart->str() << ' ';
++istart;
} // text1 text2
(?!...)
— отрицательный просмотр вперед. Выведем все слова, после которых нет запятой:
std::regex rgx("[a-z]+[0-9](?![,])");
std::string str("text1, text2, text3 text4");
std::sregex_iterator istart(str.begin(), str.end(), rgx);
std::sregex_iterator iend;
while (istart != iend) {
std::cout << istart->str() << ' ';
++istart;
} // text3 text4
Рассмотрим небольшой пример. Предположим необходимо получить все слова, расположенные после тире, причем перед тире и после слов должны следовать пробельные символы:
std::regex rgx("\\s\\-([a-z0-9]+)\\s");
std::string str("-word1 -word2 -word3 -word4 -word5");
std::sregex_iterator istart(str.begin(), str.end(), rgx);
std::sregex_iterator iend;
while (istart != iend) {
std::cout << istart->str(1) << ' ';
++istart;
} // word2 word4
Как видно из примера, мы получили только два слова вместо пяти. Первое и последнее слово не попали в результат, так как расположены в начале и в конце строки. Чтобы эти слова попали в результат, необходимо добавить альтернативные выборы: (^|\\s)
— для начала строки и (\\s|$)
— для конца строки. Чтобы найденные выражения внутри круглых скобок не попали в результат, следует добавить символы ?:
после открывающей скобки:
std::regex rgx("(?:^|\\s)\\-([a-z0-9]+)(?:\\s|$)");
std::string str("-word1 -word2 -word3 -word4 -word5");
std::sregex_iterator istart(str.begin(), str.end(), rgx);
std::sregex_iterator iend;
while (istart != iend) {
std::cout << istart->str(1) << ' ';
++istart;
} // word1 word3 word5
Первое и последнее слово успешно попали в результат. Почему же слова word2
и word4
не попали в список совпадений? Ведь и перед тире есть пробел, и после слова есть пробел. Чтобы понять причину рассмотрим поиск по шагам. Первое слово успешно попадает в результат, так как перед тире расположено начало строки, и после слова есть пробел. После поиска указатель перемещается, и строка для дальнейшего поиска примет следующий вид:
"-word1 <Указатель>-word2 -word3 -word4 -word5"
Обратите внимание на то, что перед фрагментом –word2
больше нет пробела, и тире не расположено в начале строки. Поэтому следующим совпадением станет слово word3
, и указатель снова будет перемещен:
"-word1 -word2 -word3 <Указатель>-word4 -word5"
Опять перед фрагментом –word4
нет пробела, и тире не расположено в начале строки. Поэтому следующим совпадением станет слово word5
, и поиск будет завершен. Таким образом, слова word2
и word4
не попадают в результат, поскольку пробел до фрагмента уже был использован в предыдущем поиске. Чтобы этого избежать, следует воспользоваться положительным просмотром вперед (?=...)
:
std::regex rgx("(?:^|\\s)\\-([a-z0-9]+)(?=\\s|$)");
std::string str("-word1 -word2 -word3 -word4 -word5");
std::sregex_iterator istart(str.begin(), str.end(), rgx);
std::sregex_iterator iend;
while (istart != iend) {
std::cout << istart->str(1) << ' ';
++istart;
} // word1 word2 word3 word4 word5
В этом примере мы заменили фрагмент (?:\\s|$)
на (?=\\s|$)
. Поэтому все слова успешно попали в список совпадений.
Помощь сайту
ЮMoney (Yandex-деньги): 410011140483022
ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов