Я написал систему управления контентом, которая использует регулярное выражение на стороне сервера для экранирования амперсандов в ответе страницы непосредственно перед его отправкой в браузер клиента. Регулярное выражение учитывает амперсанды, которые уже экранированы или являются частью сущности HTML. Например, следующее:
a & b, c & d, © 2009
изменяется на это:
a & b, c & d, © 2009
(Изменено только первое &
.) Вот регулярное выражение, которое было взято и изменено из помощника Rails:
html.gsub(/&(?!([a-zA-Z][a-zA-Z0-9]*|(#\d+));)/) { |special| ERB::Util::HTML_ESCAPE[special] }
Хотя это прекрасно работает, у него есть проблема. Регулярное выражение не знает о каких-либо <![CDATA[
или ]]>
, которые могут окружать неэкранированные амперсанды. Это необходимо для того, чтобы встроенный JavaScript оставался нетронутым. Например, это:
<script type="text/javascript">
// <![CDATA[
if (a && b) doSomething();
// ]]>
</script>
к сожалению, выглядит так:
<script type="text/javascript">
// <![CDATA[
if (a && b) doSomething();
// ]]>
</script>
что, конечно, механизмы JavaScript не понимают.
У меня такой вопрос: есть ли способ изменить регулярное выражение так, чтобы оно выполнялось точно так же, как сейчас, за исключением того, что текст в разделе CDATA остается нетронутым?
Поскольку регулярное выражение не так просто для начала, на этот вопрос может быть легче ответить: возможно ли написать регулярное выражение, которое изменит все буквы в точку, кроме тех букв между '<
' и '>
'? Например, тот, который изменит "some <words> are < safe! >"
в ".... <words> ... < safe! >"
?