2012-05-15 1 views
1

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

  • ([^"]|(\\[.\n]))*\"

В принципе, требования следующие:

  1. строковый литерал должен быть согласован, так что я все согласования до величин последний ", между ними может быть \", который не должен заканчивать строку.
  2. Мы также могли бы быть в состоянии избежать ничего, включая \ п с «\»
  3. Только неэкранированный «"»символ может закончить матч, больше ничего.

Некоторые строки образца, которые Мне нужно, чтобы правильно соответствовать следующие:

  1. \ а \ Ь \ "\ п" => Я должен соответствовать следующий символ '\', 'а', '\', 'B', '\', '' ',' \ ',' n ',' "'
  2. \" это все еще внутри строки "=> s hould match весь текст, включая последний '' '
  3. ' m о том, чтобы сбежать к новой строке \ '\ n' "=> В этой строке есть символ \ n, но все же строка должна соответствовать всем: от начала 'm' до заканчивается '' '.

Пожалуйста, помогите мне сформулировать такое регулярное выражение. На мой взгляд, что Regex, который я предоставил, должен выполнять эту работу, но это, скорее, неудача без причины.

+0

Я не понимаю, почему нет определенного рецепта для этой проблемы. Это стандартная проблема. На каждом языке программирования нам нужно сопоставить строковые литералы каким-то образом, и обычно мы допускаем большую свободу с \ escape-последовательностями. Для достижения этого эффекта должен быть общий рецепт (стандартное регулярное выражение). Однако я не смог найти. – VaidAbhishek

ответ

2

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

([^"\\]|\\(.|\n))*\" 

Или:

([^"\\]|\\[\s\S])*\" 
+0

Спасибо. это очень помогает. – VaidAbhishek

1

Я думаю, что это будет более эффективным:

[^"\\]*(\\.[^"\\]*)*\" 
0

Я предположил, что ваша строка также начинается с "(Если ваши примеры не начать с этим?)

Конструкция Lookaround кажется наиболее естественным для меня использовать:

".*?"(?<!\\") 

Учитывая на вход

"test" test2 "test \a test" "test \"test" "test\"" 

это будет соответствовать:

"test" 
"test \a test" 
"test \"test" 
"test\"" 

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

Match the character “"” literally «"» 
Match any single character that is not a line break character «.*?» 
    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?» 
Match the character “"” literally «"» 
Assert that it is impossible to match the regex below with the match ending at this position (negative lookbehind) «(?<!\\")» 
    Match the character “\” literally «\\» 
    Match the character “"” literally «"» 
+0

На каком языке вы используете регулярное выражение? – buckley

+0

Регулярное правило большого пальца # 37: Если это кажется естественным, вы, вероятно, ошибаетесь. : D Почти каждый из них придумывает этот подход в какой-то момент, но он терпит неудачу, если последнее перед закрывающей цитатой - это экранированная обратная косая черта - например, '" test \\ "'. –

+0

Я использую lex, поэтому мне нужно определить правила для регулярного выражения. Проблема в том, что я хочу совместить строковый литерал. Как только я соглашусь, я продолжу его обработку. Я уже сопоставляю начало », в результате чего после того, как мне придется сопоставить оставшееся волнение, которое может включать в себя что-либо на этой планете, за исключением невыпущенной двойной кавычки. Как-то я не могу этого сделать. – VaidAbhishek

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