Сделать персонажа необязательным только при последнем появлении группы захвата - PullRequest
1 голос
/ 07 апреля 2019

Я пытаюсь использовать регулярные выражения в своем приложении C ++, чтобы проверить, соответствуют ли строки общему формату типа массива. Строка должна соответствовать списку чисел, разделенных запятыми, окруженных любым количеством пробельных символов и заключенных в фигурные скобки. Итак,

 {1, 2, 3}`, 
 {12.234,2313.4231, 
 {+1.232, -2313.32,    12} 

все должны быть сопоставлены как правильные. Моя текущая строка регулярных выражений такая (пробелы добавлены для ясности):

\\{ ( \\s*?[+-]?[0-9]+\\.?[0-9]?,\\s*? )+ \\}

Проблема с этой строкой заключается в том, что запятая обязательна после каждого числа, чтобы считаться допустимой строкой. То есть строка {12, 12, 12,} работает, но строка {12, 12, 12} не совпадает из-за пропущенной последней запятой. Я мог бы сделать запятую необязательной, добавив после нее ?, но это сделало бы строку {12 12 12} допустимой, чего я хочу избежать.

Как мне сделать так, чтобы символ запятой был необязательным в last вхождении в строке?

Вот фрагмент кода, иллюстрирующий мою проблему:

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

int main()
{
    std::regex test("\\{(\\s*?[+-]?[0-9]+\\.?[0-9]?,\\s*?)+\\}");
    std::string input;
    while(1){
        std::getline(std::cin, input);
        if(input == "exit")
            break;
        if(std::regex_match(input, test))
            std::cout << "string matches" << std::endl;
        else
            std::cout << "string does not match" << std::endl;
    }
}

1 Ответ

1 голос
/ 07 апреля 2019

Если три строки, которые вы упомянули в верхней части, являются действительными ({1, 2, 3}, {12.234,2313.4231,} и {+1.232, -2313.32, 12}), вы можете использовать два подхода: чередование с положительным прогнозом, которое проверило бы, есть ли } в конец ((?:,\\s*|(?=\\}$)))

std::regex test("\\{(?:\\s*[+-]?[0-9]+\\.?[0-9]*(?:,\\s*|(?=\\}$)))+\\}");

или добавление необязательной запятой ,? перед последним }:

std::regex test("\\{\\s*[+-]?[0-9]+\\.?[0-9]*(?:,\\s*[+-]?[0-9]+\\.?[0-9]*)*\\s*,?\\}");

См. regex demo 1 и regex demo 2 .

Если {1, 2, 3,} недействительно, лучший способ - развернуть повторную группу:

std::regex test("\\{\\s*[+-]?[0-9]+\\.?[0-9]*(?:,\\s*[+-]?[0-9]+\\.?[0-9]*)*\\s*\\}"); 

См. это демо регулярных выражений .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...