Страницы

Поиск по вопросам

суббота, 11 января 2020 г.

Regexp. Передача регистра заменяемой буквы

#cpp #c #регулярные_выражения


Имеется слово, допустим, Cinderella, где Ci - превратится в Si, если введенное слово
- cinderella, то ci превратится в si. 

Как в правилах передать регистр заменяемой буквы?

 Rules->rule = {"[Cc]i", "[Cc]e", "[Cc]k", "[Cc]"}
 Rules->replacement = {"si", "se", "", "k"}

    


Ответы

Ответ 1



Предлагаю воспользоваться boost::regex, это более мощная библиотека регулярных выражений, которая поддерживает условную замену. Замените свои регулярные выражения следующими: "(?:(C)|(c))i", "(?:(C)|(c))e", "[Cc]k", "(?:(C)|(c))", И шаблоны замены на "(?1Si:si)", "(?1Se:se)", "", "(?1K:k)", К regex rule(Rules->rule[i]); добавьте приставку boost, а вместо words = regex_replace(words, rule, Rules->replacement[i]); напишите words = boost::regex_replace(words, rule, Rules->replacement[i], boost::format_all);. Именно boost::format_all позволяет использовать конструкцию типа если-то-или в шаблонах замены. См. пример работы программы: #include #include #include #include using namespace std; struct Lexer { vector rule; vector replacement; }; string Parser(string words, Lexer* Rules) { for (unsigned i = 0; i < Rules->rule.size(); i++) { boost::regex rule(Rules->rule[i]); //words = regex_replace(words, rule, Rules->replacement[i]); words = boost::regex_replace(words, rule, Rules->replacement[i], boost::format_all); } return words; } void init(Lexer* Rules) { Rules->rule = { "(\\W[Aa]\\W)", "\\W[Aa] \\W", "\\W [Aa]\\W", "^([Aa])", "(\\W[Aa])+$", "(\\W[Aa]n\\W)", "\\W[Aa]n \\W", "\\W [Aa]n\\W", "^([Aa]n)", "(\\W[Aa]n)+$", "(\\W[Tt]he\\W)", "\\W[Tt]he \\W", "\\W [Tt]he\\W", "^([Tt]he)", "(\\W[Tt]he)+$", "(?:(C)|(c))i", "(?:(C)|(c))e", "[Cc]k", "(?:(C)|(c))", "[Ee]{2}", "[Oo]{2}", "([a-zA-Z])\\1" // замена любых одинаковых букв }; Rules->replacement = { "", " ", " ", "", "", // [5] ( [A-a])+$ "", " ", " ", "", "", "", " ", " ", "", "", "(?1Si:si)", "(?1Se:se)", "", "(?1K:k)", "i", "u", "$1" }; } void output(string words) { cout << words << endl; } int main() { Lexer* Rules = new Lexer(); string words; words = "Cinderella cinderella beck and Coral"; //getline(cin, words); ::init(Rules); words = ::Parser(words, Rules); output(words); return 0; } Результат: Sinderela sinderela be and Koral. Как это работает Разберём один пример: (?:(C)|(c))i => (?1Si:si). Тут (?:(C)|(c))i находит либо C (и помещает его в подмаску №1) или c (и помещает её в подмаску №2), а потом находит i. Замену читаем следующим образом: (?1 - если подмаска №1 содержит какое-то значение, подставь Si, иначе (:) подставь si. Конец шаблона условной замены ()).

Комментариев нет:

Отправить комментарий