#c #regex #string
#c #регулярное выражение #строка
Вопрос:
Функция Извлечения
string extractStr(string str, string regExpStr) { regex regexp(regExpStr); smatch m; regex_search(str, m, regexp); string result = ""; for (string x : m) result = result x; return result; }
Основной Код
#include lt;iostreamgt; #include lt;regexgt; using namespace std; string extractStr(string, string); int main(void) { string test = "(1 1)*(n n)"; cout lt;lt; extractStr(test, "n\ n") lt;lt; endl; cout lt;lt; extractStr(test, "(\d)\ \1") lt;lt; endl; cout lt;lt; extractStr(test, "([a-zA-Z])[ -/*]\1") lt;lt; endl; cout lt;lt; extractStr(test, "([a-zA-Z])[ -/*]([a-zA-Z])") lt;lt; endl; return 0; }
Вывод
String = (1 1)*(n n) n n = n n (d) 1 = 1 11 ([a-zA-Z])[ -/*]1 = n nn ([a-zA-Z])[ -/*]([a-zA-Z]) = n nnn
Если бы кто-нибудь мог любезно указать на ошибку, которую я совершил, или указать мне на аналогичный вопрос, чтобы я пропустил во время поиска, я был бы очень признателен.
Комментарии:
1. Ожидаемый результат?
2.
for (string x : m)
не будет перебирать разные совпадения, но о группах текущего совпадения som[0]
(всего совпадения), иm[1]
..m[n]
(группа из(
..)
).
Ответ №1:
Регулярные выражения в C работают не совсем так, как «обычные» регулярные выражения. Особенно, если позже вы будете искать несколько групп. У меня также есть несколько советов по C здесь (постоянство и ссылки).
#include lt;cassertgt; #include lt;iostreamgt; #include lt;sstreamgt; #include lt;regexgt; #include lt;stringgt; // using namespace std; don't do this! // https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice // pass strings by const reference // 1. const, you promise not to change them in this function // 2. by reference, you avoid making copies std::string extractStr(const std::stringamp; str, const std::stringamp; regExpStr) { std::regex regexp(regExpStr); std::smatch m; std::ostringstream os; // streams are more efficient for building up strings auto begin = str.cbegin(); bool comma = false; // C matches regexes in parts so work you need to loop while (std::regex_search(begin, str.end(), m, regexp)) { if (comma) os lt;lt; ", "; os lt;lt; m[0]; comma = true; begin = m.suffix().first; } return os.str(); } // small helper function to produce nicer output for your tests. void test(const std::stringamp; input, const std::stringamp; regex, const std::stringamp; expected) { auto output = extractStr(input, regex); if (output == expected) { std::cout lt;lt; "test succeeded : output = " lt;lt; output lt;lt; "n"; } else { std::cout lt;lt; "test failed : output = " lt;lt; output lt;lt; ", expected : " lt;lt; expected lt;lt; "n"; } } int main(void) { std::string input = "(1 1)*(n n)"; test(input, "n\ n", "n n"); test(input, "(\d)\ \1", "1 1"); test(input, "([a-zA-Z])[ -/*]\1", "n n"); return 0; }