С++ поиск позиций совпадений регулярных выражений в строке

У меня есть несколько проблем с моим алгоритмом, пытаясь получить позиции совпадений регулярных выражений в строке. Пожалуйста, найдите код здесь - https://godbolt.org/z/aj8Gq4Moh

std::vector<int> mval;

int closed_val = 0;
int open_val = 0;
std::string da_line = "} } }";
std::smatch m;
std::regex_search(da_line, m, std::regex("([\\}]+)"));
for (auto mv : m) std::cout << mv << std::endl;
std::cout << m.size() << std::endl;
closed_val = da_line.find(m[0]);
mval.push_back(closed_val);
try {
    if (m.size() >= 1) {
        std::string db_line;
        for (int j = 1; j < m.size(); j++) {
            std::cout << da_line << std::endl;
            db_line = da_line.substr(da_line.find(m[j]) + 1, da_line.size() - 1);
            std::cout << db_line << std::endl;
            int f = db_line.find(m[j]);
            if (f == -1 || f > db_line.size() - 1)
                continue;
                std::cout << f << std::endl;
            open_val = closed_val + f + 1;
            for (auto mv : m) std::cout << mv << std::endl;
            std::cout << db_line.find(m[j + 1]) << std::endl;
            mval.push_back(open_val);
            closed_val = open_val;
            da_line = db_line;
        }
    }
}
catch (std::exception& error) {
    std::cerr << "error : " << error.what() << std::endl;
}

for (auto mv : mval) std::cout << mv << ":";
std::cout << std::endl;

Выход:

}
}
2
} } }
 } }
1
}
}
0
0:2:
  1. Почему регулярное выражение возвращает 2 совпадения, когда их 3,
  2. Ожидаемый результат 0:2:4, когда он возвращает 0:2.

Пожалуйста, отредактируйте свой пост и вырежьте и вставьте код сюда.

Ken Y-N 18.04.2023 07:43
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
69
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

У вас базовое непонимание функции std::regex_search. Он будет искать только 1 совпадение (или ничего). Пожалуйста, прочитайте еще раз здесь.

Также std::match_results работает совершенно по-другому. Но в описании std::regex_search есть действительно хорошее объяснение.

Пожалуйста, обрати внимание:

Если для вашего регулярного выражения можно найти совпадение, в основном для '}', m.size() будет 2, и только m[0] будет релевантным.

std::match_results будет содержать более одного результата, только если есть более 1 подсовпадения. Например, с регулярным выражением "a|b" у вас может быть 2 элемента.


Вы должны следовать части «Примечания» в описании функции.

Чтобы проверить все совпадения в целевой последовательности, std::regex_search может вызываться в цикле, каждый раз перезапускаясь с m[0].second предыдущего вызова. std::regex_iterator предлагает простой интерфейс для этой итерации.

И, в принципе, для вашего конкретного желания найти позиции '}' в строке вам вообще не понадобится std::regex_search. .find() в цикле было бы вполне достаточно.

Но я понимаю, что вы хотите использовать более общий подход "regex".

На данный момент я не вижу хорошего решения. Однако для вашего примера будет работать следующее:

#include <iostream>
#include <string>
#include <regex>

int main() {
    // We want to search in this string
    std::string line{ " abx    aby   abz" };

    // regex for search a }
    const std::regex re{ R"(ab?)" };

    // Here we will store the running position
    std::size_t position{};

    // Search all occurences of regex in the given string
    for (std::smatch sm; std::regex_search(line, sm, re); line = sm.suffix()) {

        // Search the character and add to current position
        position += line.find(sm[0]);

        // Show result
        std::cout << position << ' ';

        // Take length of regex into account
        position += std::string(sm[0]).size();
    }
}

Отличный пример! Спасибо за подсказку Гурнет.

SagunKho 18.04.2023 10:02
Ответ принят как подходящий

Чтобы найти все совпадения во входных данных, вы обычно хотите использовать regex_iterator (в данном случае конкретно sregex_iterator), что-то в следующем порядке:

#include <regex>
#include <iostream>
#include <string>

int main() {
    std::string s = "} } }";

    std::regex pattern("([\\}]+)");
    auto begin = std::sregex_iterator {s.begin(), s.end(), pattern};
    auto end = std::sregex_iterator();

    for (std::sregex_iterator i = begin; i != end; ++i)
    {
        std::cout << "Found match at position: " << i->position() << "\n";
    }
}

Результат:

Found match at position: 0
Found match at position: 2
Found match at position: 4

Отличный пример, спасибо за совет, Джерри.

SagunKho 18.04.2023 10:03

Другие вопросы по теме