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

2

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

Если в одной из моих строк есть запятая, она ДОЛЖНА следовать за пробелом или ровно тремя цифрами:

  • valid:,\s
  • valid:,\d\d\d

Но если за запятой следует какой-либо другой шаблон, то это ошибка:

  • неверно:,\D
  • неверно:,\d
  • неверно:,\d\d
  • недействителен:,\d\d\d\d

Лучшее регулярное выражение, которое я придумал до сих пор:

Regex CommaError = new Regex(@",(^(\d\d\d)|\S)"); // fails case #2

Чтобы проверить, я использую:

if (CommaError.IsMatch(", ")) // should NOT match
    Console.WriteLine("failed case #1");
if (CommaError.IsMatch(",234")) // should NOT match
    Console.WriteLine("failed case #2");
if (!CommaError.IsMatch("0,a")) // should match
    Console.WriteLine("failed case #3");
if (!CommaError.IsMatch("0,0")) // should match
    Console.WriteLine("failed case #4");
if (!CommaError.IsMatch("0,0a1")) // should match
    Console.WriteLine("failed case #5");

Но регулярное выражение, которое я дал выше, выходит из строя в случае №2 (оно совпадает, если оно не должно).

Я потратил несколько часов на изучение этого и обыскал в Интернете для подобных регулярных выражений, но попал в кирпичную стену. Что случилось с моим регулярным выражением?

Обновление: Peter отправил комментарий с регулярным выражением, которое работает так, как я хочу:

Regex CommaError = new Regex(@",(?!\d\d\d|\s)");

Править: Ну, почти. В этом случае он терпит неудачу:

if (!CommaError.IsMatch("1,2345")) // should match
    Console.WriteLine("failed case #6");
  • 0
    На каком языке это? Разные языки используют разные варианты регулярных выражений, которые поддерживают разные функции.
  • 0
    Питер, я использую C #.
Показать ещё 3 комментария
Теги:

2 ответа

5
Лучший ответ

Вы можете использовать ^ для обозначения не внутри класса символов (например: [^a-b]) в большинстве синтаксисов regex.

Простейшей задачей для вас было бы инвертировать условие в вашем операторе if.

Если вы не можете сделать это по какой-либо причине, вы можете использовать отрицательный lookahead в некоторых синтаксисах regex. например:

,(?!\d\d\d(?!\d)|\s)

В синтаксисах regex, которые не поддерживают отрицательные утверждения, вы все равно можете делать то, что хотите, но чем больше отрицательное совпадение, тем более сложным становится регулярное выражение. например:

,($|[^ \d]|\d$|\d[^\d]|\d\d$|\d\d[^\d]|\d\d\d\d)

По сути, вам нужно перечислить все плохие случаи.

  • 0
    Вам не нужна группа без захвата, когда вы выполняете чередование в предвкушении, с помощью ,(?!\d\d\d|\s) будет работать.
  • 0
    Питер: хорошая мысль. Это было безопасно, но не нужно. Я удалил это.
Показать ещё 4 комментария
0

На каком языке вы пытаетесь это сделать? Это perl-совместимое регулярное выражение для соответствия такому случаю: ,(?!(\s|\d{3}[^\d])) (он будет соответствовать запятым не, за которым следует пробел или точные 3 цифры, поэтому, если строка соответствует этому регулярному выражению, это недействительно)

  • 0
    Этот соответствует 233, которым он не должен соответствовать
  • 0
    Я использую C #. Используя ваше регулярное выражение, Regex CommaError = new Regex (@ ", (?! (\ S | \ d {3} [^ \ d]))"); По какой-то причине он не проходит контрольный пример №2.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню