Экранировать все двойные кавычки внутри одной строки с регулярным выражением [дубликат]


Возможный дубликат:
регулярное выражение для экранирования двойных кавычек внутри одинарных кавычек

Мне нужно регулярное выражение (никакого другого языка!!, лучше всего будет perl синтаксис REGEX или PCRE синтаксис REGEX), чтобы заменить все двойные кавычки " на ", которые находятся внутри одной строки в кавычках. Вот пример строки (часть файла):

var baseUrl = $("#baseurl").html();
var head = '<div id="finishingDiv" style="background-image:url({baseUrl}css/userAd/images/out_main.jpg); background-repeat: repeat-y; ">'+
'<div id="buttonbar" style="width:810px; text-align:right">';

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

Это должно быть конечным результатом для последней строки выше:

'<div id="buttonbar" style="width:810px; text-align:right">';

Заранее спасибо

***Обновление: Чтобы было понятно, мне нужно только регулярное выражение, а не программа perl. Регулярное выражение может быть синтаксисом Perl regex или синтаксисом PHP PCRE (который очень близок синтаксису Perl regex, насколько я понимаю). Цель состоит в том, что вы можете запустить регулярное выражение в IDES в меню поиска и замены, которые поддерживают регулярное выражение (например Затмение и PhpEd f. e)!!

Другими словами, Мне нужно регулярное выражение, которое я помещу в поле IDE поиска, которое дает мне точно все неэскапированные " в одной строке в кавычках в результате. В поле замены eclipse я могу тогда просто поставить $1, чтобы избежать их.

Они должны работать в Regexbuddy или regex coach, пожалуйста, чтобы я мог их протестировать.

По крайней мере, таков план :)


3 3

3 ответа:

Вы просили Perl (или PCRE) и ничего больше.

Хорошо.

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

  s{
      (?<! (?<! \\ ) \\{1} )
      (?<! (?<! \\ ) \\{3} )
      (?<! (?<! \\ ) \\{5} )
      (?<! (?<! \\ ) \\{7} )
      (?= " )
  }{\\}xg;

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

1 while s{

  (?(DEFINE)

    (?<unescaped>
      (?<! (?<! \\ ) \\{1} )
      (?<! (?<! \\ ) \\{3} )
      (?<! (?<! \\ ) \\{5} )
      (?<! (?<! \\ ) \\{7} )
    )

    (?<single_quote> (?&unescaped) ' )
    (?<double_quote> (?&unescaped) " )
    (?<unquoted>     [^'] *?          )

  )

  (?<HEAD>
    (?&single_quote)
    (?&unquoted)
  )

  (?<TAIL>
    (?&double_quote)
    (?&unquoted)
    (?&single_quote)

  )

}<$+{HEAD}\\$+{TAIL}>xg;

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

sub escape_quote {
  my $_ = shift;
  s{
      (?<! (?<! \\ ) \\{1} )
      (?<! (?<! \\ ) \\{3} )
      (?<! (?<! \\ ) \\{5} )
      (?<! (?<! \\ ) \\{7} )
      (?= " )
  }{\\}xg;

  return $_;
}

s{

  (?(DEFINE)

    (?<unescaped>
      (?<! (?<! \\ ) \\{1} )
      (?<! (?<! \\ ) \\{3} )
      (?<! (?<! \\ ) \\{5} )
      (?<! (?<! \\ ) \\{7} )
    )

    (?<single_quote> (?&unescaped) ' )
    (?<unquoted>     [^'] *?          )

  )

  (?<HEAD> (?&single_quote) )
  (?<TARGET> (?&unquoted) )
  (?<TAIL> (?&single_quote) )

}{
               $+{HEAD}    .
  escape_quote($+{TARGET}) .
               $+{TAIL}

}xeg;
Обратите внимание, что все это предполагает, что у вас нет законных парных неэскапированных двойных кавычек, содержащих неэскапированные одинарные кавычки. Даже что-то вроде этого сбьет вас с толку:
my $cute = q(') . "stuff" . q(');

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

Пожалуйста, не обращайте внимания на все кричащие и обманчиво неправильные так окраски. По какой-то причине он не может анализировать Perl так же хорошо, как perl. Не могу себе представить почему?. ☺

В соответствии с вашим редактированием вы хотите, чтобы универсальное регулярное выражение использовалось в функции поиска и замены неопределенного IDE или текстового редактора. Все не так просто. Я уверен, что вы знаете, что разные языки (Perl, Java, Python и т. д.) как правило, имеют свои собственные вкусы регулярных выражений, с различными наборами функций и синтаксическими причудами. Ситуация среди редакторов и IDE еще хуже.

Обновление:, поскольку я написал Это, визуальная студия перешла к использованию .Чистый вкус, и Notepad++ имеет принял библиотеку Boost. Приведенное ниже регулярное выражение теперь будет работать во всех редакторах / IDE, о которых я упоминал, за исключением Visual Studio. (.NET не поддерживает притяжательные кванторы, но у него есть атомарные группы, которые можно использовать с тем же эффектом.)

JEdit и IntelliJ IDEA, будучи написаны на Java, используют регулярное выражение Java, что довольно хорошо. Но Visual Studio не использует превосходный вкус .NET; вместо этого она использует устаревший вкус с эклектичным набором функций и причудливым синтаксисом. TextMate, редактор Mac, которым восхищаются разработчики Apple, использует многофункциональный аромат Oniguruma, но Notepad++ (бесплатный редактор Windows, который также получает много хорошей прессы)использует аромат с чрезвычайно ограниченным набором функций-он даже не поддерживает чередование!

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

Поиск: \G((?:(?:\A|')[^']*+')?+[^'"]*+)"([^'"]*+)

Заменить: $1\\"$2

(это предполагает, что каждый Апостроф используется в качестве цитаты; что ни один из них не должен игнорироваться, потому что они находятся в комментариях, строках с двойными кавычками или что-то еще; что в тексте нет экранированных кавычек (одинарных или двойных); и список продолжается.)

\G (якорьend-of-previous-match ) является существенным, но это функция, которая не поддерживается даже некоторыми из наиболее популярных типов регулярных выражений, таких как JavaScript и Питон. Притяжательные кванторы (*+, ?+) Держите регулярное выражение от увязания, когда совпадение невозможно; они доступны в PCRE, Oniguruma, Perl 5.10+ и Java. .NET не имеет их, но у него есть несколько более неуклюжая альтернатива, атомарные группы.

Я предлагаю вам забыть о подходе generic-regex и стандартизировать набор инструментов, который имеет необходимые вам возможности. Для общих целей я не думаю, что что-то превосходит семейство инструментов JGSoft: EditPad Pro, PowerGrep и RegexBuddy. Как в функциях, так и в производительности, jgsoft regex flavor ничем не уступает другим; все, чего ему не хватает,-это рекурсивного соответствия и встроенного кода.

P. s. я вижу, что Вы упомянули Eclipse в комментарии; у меня его нет, но я ожидаю, что он использует Java regex flavor (или, возможно, ICU flavor, синтаксис которого практически идентичен Java), поэтому регулярное выражение выше должно работать в нем.

Пока есть только одна строка в одинарных кавычках на строку (как в вашем примере), это должно работать (синтаксис sed):

s|'\([^'"]*\)"\([^']*\)'|'\1\"\2'|g