2009-12-25 4 views
0

У меня возникли некоторые проблемы. В моей строке может быть специальный символ/символ новой строки «\ г \ п».NET Regex синтаксический анализ символа новой строки

Часть моего регулярного выражения:

string sRegex = "(?<string>\"+.*\"|'+.*')"; 

Как я должен изменить это регулярное выражение, чтобы исключить строку из моей строки?

Спасибо за помощь.

+9

венгерское название в C#, да?

+0

Это поможет, если вы можете включить примеры того, что вы хотите совместить/исключить. –

+0

Возможно, 's' означает строку, которую должно соответствовать регулярное выражение, а не сама строка регулярных выражений. Во всяком случае, можно надеяться. ;) –

ответ

2

В большинстве языков (за исключением Ruby, я думаю) многострочный синтаксический анализ должен быть включен явно. По многострочному разбору я подразумеваю, в частности, символ новой строки явно, а не неявно завершая соответствие новой строке.

В DotNet вы хотите сделать:

Regex.Match("string", "regex", RegexOptions.Multiline) 

и «регулярное выражение» должен был бы содержать строки с явно указанными символами новой строки, как

"regex\nnewline" 

, который будет соответствовать внутри 2 строки:

hello 
regex 
newline 
world 
0

Вы можете попробовать что-то вроде этого:

string sRegex = "(?<string>\"+(.*[\r\n]*)\"|'+(.*[\r\n]*)*')"; 

Она должна охватывать строку, как этот

"Akim 
Khalilov 
StackOverflow" 

Я уверен, что это регулярное выражение может быть оптимизирована.

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

2

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

Посмотрите на Регулятор Regex Workbench (http://code.msdn.microsoft.com/RegexWorkbench). Это отличный инструмент для выяснения правильного регулярного выражения. Бинарные файлы предназначены для очень старой .NET, но вы можете перекомпилировать ее. (http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regexoptions(VS.71).aspx), в особенности RegexOptions.MultiLine. Вероятно, это то, что вам нужно.

Существует два способа указать опции: RegexOptions и «inline contructs» (http://msdn.microsoft.com/en-us/library/yd1hzczs(VS.71).aspx). Например, MultiLine может быть определен как:

string sRegex = "(?<string>\"+.*\"|'+.*')?m"; 

Несколько дополнительных примечаний:

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

Я предпочел бы хранить свое регулярное выражение в объекте Regex, чем в строке, так как это более насыщенная типизация.Исключение для меня - это когда я составляю строки для создания нового регулярного выражения. В этом случае я вызываю переменную fooRegexText, чтобы сделать это ясно.

Я считаю, что регулярные выражения любой сложности трудно читать. Я использую пробелы в регулярном выражении, чтобы помочь моему бедному мозгу (используя IgnorePatternWhitespace).

Применяя те, я бы написать:

 Regex regex = new Regex(
@"(?mx) # MultiLine, IgnorePatternWhitespace 
    (?<string> 
     ""+.*"" 
      | 
     '+.*' 
    ) 
"); 
2

Вы говорите, вы хотите, чтобы соответствовать строки в кавычках, только если они не содержат символы новой строки? Если это так, вам не нужно делать ничего особенного, потому что точка по умолчанию не соответствует символам новой строки. Помимо + после вступительных цитат (что не имеет для меня никакого смысла), ваше регулярное выражение должно работать нормально. Но второе предложение Джея использовать дословные строковые литералы для написания регулярных выражений:

Regex sRegex = new Regex(@"(?<string>"".*""|'.*')"); 

Что вы сделать нужно следить за это алчность. Например, если есть две строковые объявления на той же линии, как это:

var s1 = "foo", s2 = "bar"; 

... регулярное выражение будет найти один матч, "foo", s2 = "bar", где вы ожидали, чтобы соответствовать "foo" и "bar" отдельно. Чтобы избежать этого, вы можете использовать не жадный квантор:

Regex sRegex = new Regex(@"(?<string>"".*?""|'.*?')"); 

Если вы сделать хотите, чтобы соответствовать строки с символами новой строки в них, вы можете использовать Singleline вариант, который изменяет поведение из точка, позволяя ему соответствовать новым строкам.

Regex sRegex = new Regex(@"(?<string>"".*?""|'.*?')", 
         RegexOptions.Singleline); 

... или вы можете использовать встроенный модификатор:

Regex sRegex = new Regex(@"(?s)(?<string>"".*?""|'.*?')"); 

Имейте в виду, что при использовании точки в SingleLine режиме это особенно важно, что вы используете, не жадный квантор, так как потенциал совпадения больше не ограничиваются одной строкой. Но вот еще одна альтернативы, которая более эффективна, а также более предсказуемые:

Regex sRegex = new Regex(@"(?<string>""[^""]*""|'[^']*')"); 

Там нет необходимости указывать SingleLine режима с этим регулярным выражением, потому что вы не используете точку метасимволы. Отрицательный класс символов [^"] соответствует любому символу, за исключением кавычки, включая символы новой строки.


Наконец, я хотел бы сказать несколько слов о параметре Multiline, так как там, кажется, много путаницы об этом. Люди склонны предполагать, что вы должны использовать его, когда целевой текст состоит из нескольких строк (т. Е. Всякий раз, когда он содержит символы новой строки). Это естественное предположение, но это неправда.

Весь многострочный режим изменяет поведение стартовых и конечных якорей, ^ и $. Обычно они соответствуют только началу и концу всей строки, но если вы включаете многострочный режим, они также совпадают в начале и конце логических строк внутри строки.Например, если строка объявлена ​​так:

"fee fie\nfoe fum" 

Если вы ищете регулярное выражение ^\w+ в режиме по умолчанию, вы получите один матч: fee. Но если вы переключитесь на многострочный режим, вы получите два: fee и foe. Аналогично, \w+$ соответствует только fum в режиме по умолчанию, но соответствует fie и fum в многострочном режиме. И вы всегда можете сопоставить литерал \n независимо от того, в каком режиме вы находитесь: одинарная линия, многострочная или по умолчанию.

Люди также склонны считать, что однолинейные и многострочные взаимно исключают друг друга, а это не так. Я даже видел, что люди говорят, что singleline является режимом по умолчанию; также не соответствует действительности. Singleline изменяет поведение точки (.), Multiline изменяет поведение анкеров (^ и $); это все.

Смежные вопросы