Я перебираю тысячи строк с различными регулярными выражениями для проверки простых ошибок. Я хотел бы добавить регулярное выражение, чтобы проверить правильность использования запятых.
Если в одной из моих строк есть запятая, она ДОЛЖНА следовать за пробелом или ровно тремя цифрами:
Но если за запятой следует какой-либо другой шаблон, то это ошибка:
Лучшее регулярное выражение, которое я придумал до сих пор:
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");
Вы можете использовать ^
для обозначения не внутри класса символов (например: [^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)
По сути, вам нужно перечислить все плохие случаи.
,(?!\d\d\d|\s)
будет работать.
На каком языке вы пытаетесь это сделать? Это perl-совместимое регулярное выражение для соответствия такому случаю: ,(?!(\s|\d{3}[^\d]))
(он будет соответствовать запятым не, за которым следует пробел или точные 3 цифры, поэтому, если строка соответствует этому регулярному выражению, это недействительно)