Вы говорите, что хотите сопоставить строки в кавычках, только если они не содержат символы новой строки? В таком случае ничего особенного делать не нужно, поскольку точка по умолчанию не соответствует символу новой строки. Помимо +
после открывающих кавычек (что для меня не имеет смысла), ваше регулярное выражение должно работать нормально. Но я поддерживаю предложение Джея использовать дословные строковые литералы для написания регулярных выражений:
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>"".*?""|'.*?')");
Имейте в виду, что при использовании точки в однострочном режиме особенно важно использовать не жадный квантификатор, поскольку потенциальные совпадения больше не ограничиваются одной строкой. Но вот еще одна альтернатива, более эффективная и более предсказуемая:
Regex sRegex = new Regex(@"(?<string>""[^""]*""|'[^']*')");
Нет необходимости указывать однострочный режим с этим регулярным выражением, потому что вы не используете метасимвол точки. Класс инвертированных символов [^"]
соответствует любому символу, кроме кавычек, включая символы новой строки.
Наконец, я хотел бы сказать несколько слов о параметре Multiline
, поскольку он вызывает большую путаницу. Люди склонны предполагать, что вы должны использовать его всякий раз, когда целевой текст состоит из нескольких строк (то есть, когда он содержит символы новой строки). Это естественное предположение, но это неправда.
Все, что делает многострочный режим, - это изменение поведения начальной и конечной привязок, ^
и $
. Обычно они соответствуют только началу и концу всей строки, но если вы включите многострочный режим, они также совпадают в начале и конце логических строк внутри строки. Например, для строки, объявленной так:
"fee fie\nfoe fum"
Если вы выполните поиск регулярного выражения ^\w+
в режиме по умолчанию, вы получите одно совпадение: fee
. Но если вы переключитесь в многострочный режим, вы получите два: fee
и foe
. Аналогично, \w+$
соответствует только fum
в режиме по умолчанию, но соответствует fie
и fum
в многострочном режиме. И вы всегда можете сопоставить литерал \n
независимо от того, в каком режиме вы находитесь: однострочном, многострочном или по умолчанию.
Люди также склонны считать, что однострочные и многострочные взаимоисключающие элементы, но на самом деле это не так. Я даже видел, как люди говорят, что однострочный режим является режимом по умолчанию; тоже неправда. Singleline
изменяет поведение точки (.
), Multiline
изменяет поведение якорей (^
и $
); это все.
person
Alan Moore
schedule
26.12.2009