2012-02-13 3 views
1

Я пытаюсь написать регулярное выражение в Ruby, чтобы проверить строку, таких как:
"GET \"anything/here.txt\""рубин регулярное выражение о избежать побег

дело, все может быть во внешней двойной кавычки, но все двойные кавычки в внешние двойные кавычки должны быть экранированы обратной косой чертой (иначе это не соответствует). Так, например,
"GET "anything/here.txt""
это не будет правильная линия.

Я пробовал много способов писать регулярное выражение, но делать работу. Кто-нибудь может мне с этим помочь? спасибо

ответ

5

Вы можете использовать положительный: 'назад

/\A"((?<=\\)"|[^"])*"\z/

Это именно то, что вы просили: «если двойные кавычки появляется внутри внешних двойных кавычках без обратной косой черты приставкой, это не соответствует.»

Некоторые комментарии:

\A, \z: Это матч только в начиная и конец строки. Таким образом, шаблон должен совпадать с строкой , а не ее частью. (?<=): Это синтаксис для положительного lookbehind; он утверждает, что шаблон должен соответствовать непосредственно перед текущей позиции. Итак, (?<=\\)" соответствует «двойной кавычки, которой предшествует обратная косая черта». [^"]: Это соответствует «любому символу, который не является обратным слэшем».

Одна точки об этом регулярном выражении, является то, что он будет соответствовать внутренней кавычке, который предшествует два обратные косой черты. Если это проблема, отправьте комментарий, и я исправлю это.

Если ваша версия Ruby, не имеет просмотра назад, вы могли бы сделать что-то вроде:

/\A"(\\.|[^"\\])*"\z/

Обратите внимание, что в отличие от первого регулярного выражения, это не считать двойной обратной косой черты, как избежать цитата (скорее, первая обратная косая черта ускользает от второй), поэтому "\\"" не будет соответствовать.

+0

Привет Большое спасибо. Это очень хороший способ сделать это. Но одна проблема: моя рубиновая версия - 1.8.6, которая не поддерживает '?'. Есть ли у вас какие-либо идеи по этому поводу? спасибо –

+0

@AllanJiang, я добавлю другое решение, которое не будет использовать lookbehind. –

+0

Спасибо, что он работает так, как я сказал ... но я нашел еще одну проблему с вашим ответом ... в моей ситуации я хочу, чтобы это совпадало, только двойные кавычки скрываются во внешней двойной кавычки, но в этом случае это не работает, когда такие вещи случаются "GET/class/\" notes \ ". txt \" '(последний двойной qoute также экранирован), что означает, что внешняя цитата также экранируется. Я не хочу, чтобы в этом случае была скрыта внешняя двойная кавычка ... но не может найти решение ... Не уверен, что вы можете это исправить? спасибо –

0

Испытано это на Rubular успешно:

\"GET \\\".*\\\"\"

Разбивка:
\»- побег "для регулярных выражений строки, то есть буквальный символ"
GET - Предположим, что вы просто хотите ПОЛУЧИТЬ чем это явствует
\\ "- Escape \ and", чтобы получить буквенную строку \ "
. * - 0 или более любого символа, кроме \ n
\\" \ "- Escapes for буквальное \ ""

+0

@andrewrockwell привет это работает для моего примера спасибо. Но '\' 'во внешних двойных кавычках может быть где угодно еще, например:' 'GET/class/\" notes \ ". Txt" 'и ваш ответ не будет работать для этого. Пожалуйста, взгляните на мой комментарий спасибо за ответ! –

1

Это работает:

/"(?<method>[A-Z]*)\s*\\\"(?<file>[^\\"]*)\\""/ 

Посмотри на Rubular.

Edit:

"(?<method>[A-Z]*)\s(?<content>(\\\"|[a-z\/\.]*)*)" 

Посмотри here.

Edit 2: без (? ...) последовательность (для Ruby 1.8.6):

"([A-Z]*)\s((\\\"|[a-z\/\.]*)*)" 

Rubular here.

+0

Благодарим вас за ответ, но есть вопрос, что '' '' в строке может появиться где угодно, например, он не будет работать с этими примечаниями GET/class/\ " \ ". txt" 'Так что мне просто интересно, есть ли способ сделать это:« если двойная цитата появляется во внешней двойной кавычки без префикса обратной косой черты, она не соответствует « –

+0

@AllanJiang», см. обновленный ответ. Это поведение, которое вы ожидаете? – user2398029

+0

Обновлен снова для старой версии Ruby. – user2398029

0

Я не уверен, что регулярное выражение действительно является вашим лучшим инструментом здесь, но если вы настаиваете на его использовании, я рекомендую думать о строке как о последовательности токенов: цитата, а затем ряд вещей, которые либо \\ , \" или что-то, что не является цитатой, а затем заключительной цитатой в конце. Таким образом:

^"(\\\\|\\"|[^"])*"$ 
Смежные вопросы