Класс регулярных выражений .NET и перевод строки - PullRequest
5 голосов
/ 13 июня 2009

Почему регулярное выражение .NET не обрабатывает \ n как символ конца строки?

Пример кода:

string[] words = new string[] { "ab1", "ab2\n", "ab3\n\n", "ab4\r", "ab5\r\n", "ab6\n\r" };
Regex regex = new Regex("^[a-z0-9]+$");
foreach (var word in words)
{
    Console.WriteLine("{0} - {1}", word, regex.IsMatch(word));
}

И вот ответ, который я получаю:

ab1 - True
ab2
 - True
ab3

 - False
 - False
ab5
 - False
ab6
 - False

Почему регулярное выражение соответствует ab2\n?

Обновление: Я не думаю, что Multiline является хорошим решением, то есть я хочу проверить логин, чтобы он совпадал только с указанными символами, и он должен быть однострочным Если я изменяю конструктор для параметра MultiLine, ab1, ab2, ab3 и ab6 соответствуют выражению, ab4 и ab5 не соответствуют ему.

Ответы [ 6 ]

10 голосов
/ 25 февраля 2010

Механизм регулярных выражений .NET обрабатывает \n как конец строки. И это проблема, если ваша строка имеет разрывы строк в стиле Windows \r\n. При включенном RegexOptions.Multiline $ соответствует \r и \n, а не \r.

$ также совпадает в самом конце строки, как \z. Разница в том, что \z может соответствовать только в самом конце строки, в то время как $ также соответствует перед завершающим \n. При использовании RegexOptions.Multiline, $ также совпадает перед любым \n.

Если у вас возникли проблемы с разрывами строк, уловка заключается в том, чтобы сначала выполнить поиск и замену, чтобы заменить все \r ничем, чтобы убедиться, что все строки заканчиваются только на \n.

9 голосов
/ 13 июня 2009

Если строка заканчивается разрывом строки, RegexOptions.Multiline не будет работать. $ будет просто игнорировать последний разрыв строки, так как после этого ничего не будет.

Если вы хотите соответствовать до самого конца строки и игнорировать любые разрывы строк, используйте \z

Regex regex = new Regex(@"^[a-z0-9]+\z", RegexOptions.Multiline);

Это касается как MutliLine, так и SingleLine, это не имеет значения.

1 голос
/ 27 августа 2010

Использовать параметры регулярного выражения, System.Text.RegularExpressions.RegexOptions :

string[] words = new string[] { "ab1", "ab2\n", "ab3\n\n", "ab4\r", "ab5\r\n", "ab6\n\r" }; 
Regex regex = new Regex("^[a-z0-9]+$"); 
foreach (var word in words) 
{ 
    Console.WriteLine("{0} - {1}", word,
        regex.IsMatch(word,"^[a-z0-9]+$",
            System.Text.RegularExpressions.RegexOptions.Singleline |
            System.Text.RegularExpressions.RegexOptions.IgnoreCase |
            System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace)); 
}
1 голос
/ 13 июня 2009

С RegexOptions:

Многострочный режим. Изменяет значение ^ и $, чтобы они соответствовали началу и концу, соответственно, любой строки, а не только началу и концу всей строки.

Таким образом, в основном, если вы передаете RegexOptions.Multiline конструктору Regex, вы указываете этому экземпляру обработать окончательный $ как совпадение для символов новой строки, а не просто конец строки сам по себе.

0 голосов
/ 13 июня 2009

Просто, чтобы дать больше деталей Смази ответ. Это выдержка из: Поваренная книга регулярных выражений Яна Гойваертса и Стивена Левитана. Copyright 2009 Ян Гойваертс и Стивен Левитан, 978-0-596-2068-7

Разница между ‹\ Z› и ‹\ z› вступает в игру, когда последний символ в вашем предметном тексте является Разрыв строки. В этом случае ‹\ Z› может матч в самом конце предмета текст, после окончательного переноса строки, как ну, как раз перед этой строкой перерыв. Преимущество в том, что вы можете искать ‹omega \ Z› без необходимости беспокоиться о снятии трейлинг разрыв строки в конце вашей темы текст. При чтении файла строка линия, некоторые инструменты включают в себя линию перерыв в конце строки, тогда как другие не делают; ‹\ Z› маскирует это разница. ‹\ Z› соответствует только на самый конец предметного текста, так что не будет соответствовать тексту, если конечная строка перерыв следует. Якорь ‹$› есть эквивалентно ‹\ Z›, если вы делаете не включайте совпадения «^ и $ в строке» перерывы ». Эта опция отключена по умолчанию для всех типов регулярных выражений, кроме Рубин. Руби не предлагает способ выключите эту опцию. Так же, как ‹\ Z›, ‹$› Матчей в самом конце Тематический текст, а также до окончательный перевод строки, если есть.

Конечно, я бы не нашел его без смазного ответа.

0 голосов
/ 13 июня 2009

Может быть обычная разница между окончанием строки windows / linux. Но все же странно, что \n\n получает ложь таким образом ... Вы пробовали с установленным флагом RegexOptions.Multiline?

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