Проверка строки на основе пользовательского формата - PullRequest
5 голосов
/ 17 апреля 2020

Я хочу проверить строку на основе пользовательского формата: (_.__,_.__). Это должен быть десятичный ввод, за которым следует запятая, за которой следует еще один десятичный ввод, заключенный в скобки, например (1.01,3.21). Я хочу, чтобы строковый шаблон принимал одну или несколько записей, например (1.01,3.21)(3.01,4.51)...(2.1,5.6). Возможно ли это сделать?

Ответы [ 3 ]

2 голосов
/ 17 апреля 2020

Один из способов решения этой проблемы:

  • Используйте RegEx для возврата совпадений шаблона (x,y).
  • Используйте методы расширения для извлечения x и y.
  • Проверьте, относятся ли x и y к типу decimal, используя метод decimal.TryParse(..).
  • Проверьте, содержит ли входная строка что-то другое, кроме требуемого шаблона .
private bool IsValidInput(string input)
{
    var pattern = @"\((.*?)\s?,\s?(.*?)\)";
    var xpatt = @"\s+\(|\s+\)|\,\(|\)\,|\)\s+|\({2,}|\){2,}|^\)\(|\)\($";
    var q = Regex.Matches(input, pattern)
        .Cast<Match>()
        .SelectMany(x => x.Groups.Cast<Group>()
        .Skip(1))
        .Select(x => x.Value);

    return !Regex.IsMatch(input, xpatt)
        && q.Count() > 0 
        && input.Replace(" ","").Length 
        == (input.Count(x => x == '(' || x == ')' || x == ',') 
        + q.Sum(x => x.Length))
        && q.All(x => decimal.TryParse(x, out _));
}

Итак, функция возвращает:

(1.01, 3.21)(3.01, 4.51)(2.1, 5.6)     => true
(abc, 3.21)(3.01, 4.51)(2.1, 5.6)      => false
(3.21)(3.01, 4.51)(2.1, 5.6)           => false
1.01, 3.2 13.01, 4.51 2.1, 5.6         => false
1.01, 3.21)(3.01, 4.51)(2.1, 5.6)      => false
(1.01, 3.21)(3.01, 4.51)(2.1, 5.6      => false
1.01, 3.21)3.01, 4.51)2.1, 5.6)        => false
(1.01, 3.21)3.01, 4.51(2.1, 5.6)       => false
(1.01, 3.21)abc(3.01, 4.51)(2.1, 5.6)  => false
(1.01, 3.21)(3.01, 4.51)abc(2.1, 5.6)  => false
abc(1.01, 3.21)(3.01, 4.51)(2.1, 5.6)  => false
(1.01, 3.21)(3.01, 4.51)(2.1, 5.6)abc  => false
0 голосов
/ 17 апреля 2020

Вы можете использовать

(?:\(\d+(?:\.\d+)?,\d+(?:\.\d+)?\))+

или с глобальным флагом

\(\d+(?:\.\d+)?,\d+(?:\.\d+)?\)

Первое решение будет соответствовать вашему шаблону 1 или более раз и возвращает одно совпадение , Второй будет соответствовать вашему шаблону только один раз. Однако с глобальным флагом вы получите все совпадения в виде отдельных результатов.

Объяснение:

(?:                   //begin non-capturing group
  \(                  //match opening parentheses
    \d+               //match 1 or more numbers
    (?:\.\d+)?        //optionally match a dot followed by 1 or more numbers
    ,                 //match a comma
    \d+(?:\.\d+)?     //same pattern as before comma
  \)                  //match closing parentheses
)+                    //close non-capturing group, match the group 1 or more times
0 голосов
/ 17 апреля 2020

Я думаю, что это должно помочь вашей проблеме: ^(?:\(\d+(?:\.\d+)?,\d+(?:\.\d+)?\))+$ попробуйте В настоящее время я сделал все группы захвата не захватывая группы, так как я не был уверен насчет каких-либо определенных c подгрупп, которые вы хотели бы захвата.

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