EOL Special Char не соответствует - PullRequest
4 голосов
/ 19 марта 2010

Я пытаюсь найти каждый шаблон "a -> b, c, d" во входной строке. Шаблон, который я использую, следующий:

"^[ \t]*(\\w+)[ \t]*->[ \t]*(\\w+)((?:,[ \t]*\\w+)*)$"

Этот шаблон является шаблоном C #, "\ t" относится к табуляции (это один экранированный литерал, интерпретируемый .NET String API), "\ w" относится к хорошо известному предопределенному классу регулярных выражений Значение двойного экранирования интерпретируется как «\ w» API .NET STring, а затем как «WORD CLASS» .NET Regex API.

Ввод:

a -> b
b -> c
c -> d

Функция:

private void ParseAndBuildGraph(String input) {
    MatchCollection mc = Regex.Matches(input, "^[ \t]*(\\w+)[ \t]*->[ \t]*(\\w+)((?:,[ \t]*\\w+)*)$", RegexOptions.Multiline);
    foreach (Match m in mc) {
        Debug.WriteLine(m.Value);
    }
}

Вывод:

c -> d

На самом деле, существует проблема с окончанием строки специальным символом "$". Если я вставлю «\ r» перед «$», это сработает, но я подумал, что «$» будет соответствовать любому завершению строки (с параметром «Многострочный»), особенно \ r \ n в среде Windows. Разве это не так?

Ответы [ 3 ]

7 голосов
/ 20 марта 2010

Это меня тоже удивило. В регулярных выражениях .NET $ не совпадает до разделителя строк , оно совпадает до перевода строки - символа \n. Такое поведение согласуется с регулярным выражением Perl, но, на мой взгляд, все еще неправильно. Согласно стандарту Unicode , $ должно совпадать до любого из:

\n, \r\n, \r, \x85, \u2028, \u2029, \v или \f

... и никогда не совпадать между \r и \n. Java соответствует этому (кроме \v и \f), но .NET, появившаяся намного позже Java и поддерживающая Unicode по крайней мере так же хорошо, как Java, распознает только \n. Можно подумать, что они по крайней мере будут правильно обрабатывать \r\n, учитывая, как сильно Microsoft связана с этим разделителем строк.

Имейте в виду, что . следует той же схеме: он не соответствует \n (если не установлен однострочный режим), но соответствует соответствует \r. Если бы вы использовали .+ вместо \w+ в своем регулярном выражении, вы, возможно, не заметили эту проблему; возврат каретки был бы включен в совпадение, но консоль проигнорировала бы его при печати результатов.

РЕДАКТИРОВАТЬ: Если вы хотите разрешить возврат каретки, не включив ее в свои результаты, вы можете заменить якорь на следующую: (?=\r?\n.

1 голос
/ 20 марта 2010

Обычно в C, C ++, C # строки в программе используют «\ n» в качестве разделителя строк. «\ r \ n» появляется только на уровне ввода / вывода, если включены переводы текстового режима.

1 голос
/ 19 марта 2010

Вы имеете в виду \t как регулярное выражение \t или C # \t? Я всегда использую дословные строковые литералы с регулярным выражением:

@"^[ \t]*(\w+)[ \t]*->[ \t]*(\w+)(,[ \t]*\w+)*$"

(единственное, что вам нужно - это " до "")

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