Замена строки Javascript - каков наилучший способ сделать это? - PullRequest
4 голосов
/ 04 февраля 2010

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

У меня есть следующая строка ввода:

#> Some text goes here, and a 'quoted string' is inside.
<# something with 'quotes' #>
Another 'quoted string' is found <#

Мне нужно заменить каждый символ ' в кавычках на экранированную версию \' всякий раз, когда он находится между последовательностями #> и <#.

Желаемая выходная строка:

#> Some text goes here, and a \'quoted string\' is inside.
<# something with 'quotes' #>
Another \'quoted string\' is found <#

Обратите внимание, что кавычки в части <# something with 'quotes' #> не были экранированы, только кавычки, найденные между #> и <#.

Я использую следующий код, чтобы выполнить это , но я хотел бы найти лучший или более эффективный способ сделать то же самое (ПРИМЕЧАНИЕ: возврат каретки и вкладки гарантированно не быть найдены в моей входной строке, поэтому я могу использовать их следующим образом:

var s = ... some input string ...;

// Replace all "<#" sequences with tabs "\t"
s = s.split("<#").join("\t"); 

var i = 1;
do
{
    // Replace a single quote that is found within
    // #> and <# block with a carriage return.
    s = s.replace(/((^|#>)[^\t]*?)'/g, "$1\r");

    // Continue replacing single quotes while we're
    // still finding matches.
    s = s.split("\r");
    if (s.length < ++i)
        break;
    s = s.join("\r");
}
while (true);

// Replace each instance of a carriage return
// with an escaped single quote.
s = s.join("\\'");

Основная причина, по которой я не использую только одно регулярное выражение, заключается в том, что я не могу заставить его заменить более 1 символа одинарных кавычек. Поэтому я прибег к циклу do / while, чтобы убедиться, что все они экранированы.

У кого-нибудь есть лучший способ (пожалуйста)?

Ответы [ 2 ]

4 голосов
/ 04 февраля 2010

Это регулярное выражение соответствует кавычкам не внутри <# ... #>

'(?=((?!#>)[\s\S])*(<#|$))

краткое объяснение:

'             # match a single quote
(?=           # start positive look ahead
  (           #   start capture group 1
    (?!       #     start negative look ahead
      #       #       match the character '#'
      >       #       match the character '>'
    )         #     end negative look ahead
    [\s\S]    #     match any character from the set {'0x00'..'ÿ'}
  )*          #   end capture group 1 and repeat it zero or more times
  (           #   start capture group 2
    <         #     match the character '<'
    #         #     match the character '#'
    |         #     OR
    $         #     match the end of the input
  )           #   end capture group 2
)             # end positive look ahead

или, простым языком:

Соответствует одиночной кавычке, только если смотреть вперед, можно увидеть подстроку «<#» (или конец ввода), не встречая «#>» между одинарной кавычкой и «<#» (или конец ввода). </em>

Но это решение регулярных выражений не будет более эффективным, чем то, что у вас есть сейчас (эффективно, как в: работает быстрее).

Почему вы ищете что-то кроме вашего нынешнего подхода? Ваше решение выглядит хорошо для меня.

0 голосов
/ 04 февраля 2010

Следующее регулярное выражение работает очень быстро в консоли firebug для тысяч символов.

str.replace(/'|\\'/g, "\\'")
   .replace(/(<#[^#\>]*)\\'([^\\']+)\\'([^#\>]*#\>)/g, "$1'$2'$3")

Первый заменяет все кавычки и уже экранированные кавычки на \ ' Второй ищет все <# ... \ '... \' ... #> и заменяет его на <# ...'...'... #>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...