Надежный способ скрыть фрагменты текста во время поиска и замены? - PullRequest
1 голос
/ 07 сентября 2011

Допустим, у меня есть какой-то текст:

<hello> <world> <:how> are <you>

Теперь я хочу закодировать его в HTML, чтобы <> не мешали.Но <:how> особенный, потому что в нем есть :, поэтому я не хочу его трогать.

Я могу заменить его с помощью регулярного выражения на что-то вроде {{how}}, а затем выполнить HTMLкодирование, а затем заменить его обратно.

Но что, если {{something}} уже появляется где-то в коде?Тогда {{something}} преобразуется в <:something>, когда его следует оставить как есть.

Я сталкивался с этой проблемой несколько раз в прошлом и до сих пор не нашел хорошего способа подойтиЭто.Люди просто выбирают что-то непонятное для замены и надеются , что его не существует в другом месте, или есть правильный способ сделать это?

Ответы [ 2 ]

2 голосов
/ 07 сентября 2011

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

Учитывайте это регулярное выражение: <(?!:): оно соответствует любому <, за которым не следует :, но двоеточие не включено в совпадение, поэтому вы можете просто использовать строку замены &lt;.

Узнайте, где в вашем любимом текстовом редакторе установлен флажок «использовать регулярные выражения». (В vi это неявно там, проверено.) Выражение выше работает, только если ваш редактор поддерживает приличный синтаксис регулярных выражений; большинство делают сейчас.

Но ваш оригинальный подход также выполним. Если нецелесообразно перечислять несколько сложных шаблонов исключений в регулярном выражении, вы можете временно заменить эти шаблоны некоторыми строками. Просто сделайте эти струны уникальными. Могу поспорить, что если вы замените <: на LESS=THAN=AND=COLON, то вероятность того, что вы столкнулись с чем-то или забыли, что означает эта строка, равна нулю. Да, эти временные строки являются бельмом на глазу: это дает вам шанс забыть заменить их обратно довольно тонкими.

1 голос
/ 07 сентября 2011

Вы могли бы реализовать механизм экранирования, основанный на некоторых символах, которые не выдержат процесс кодирования. Например, если вы вводите html-кодирование своего ввода, вы знаете, что после этого у вас не будет никаких символов < или >, поскольку они заменяются HTML-сущностями. Таким образом, вы можете использовать в качестве escape-кода строку из < или >. Если вы собираетесь отображать окончательный код в браузере, вы можете использовать что-то вроде <!-- TOKEN --> в качестве escape-кода, так как это не повлияет на визуализацию.

Ваш процесс кодирования может выглядеть следующим образом:

  • строка ввода:
    • <hello> {{world}} <:how> are <you>
  • заменить <xxx> на &lt;xxx&gt;, где xxx не начинается с :
    • &lt;hello&gt; {{world}} <:how> are &lt;you&gt;
  • заменить <:xxx> на {{<!-- TOKEN -->xxx}}
    • &lt;hello&gt; {{world}} {{<!-- TOKEN -->how}} are &lt;you&gt;

Отображается в браузере, {{world}} и {{how}} будут выглядеть одинаково, но они сохранят информацию о декодировании. Действительно, соответствующий процесс декодирования будет:

  • входная строка:
    • &lt;hello&gt; {{world}} {{<!-- TOKEN -->how}} are &lt;you&gt;
  • заменить {{<!-- TOKEN -->xxx}} на <:xxx>
    • &lt;hello&gt; {{world}} <:how> are &lt;you&gt;
  • заменить &lt;xxx&gt; на <xxx>
    • <hello> {{world}} <:how> are <you>

Как я уже сказал, поскольку символы, на которых вы основали свой управляющий код, не могут появиться сами по себе в закодированном тексте, так как ввод, например {{<!-- TOKEN -->how}}, не нарушит процесс кодирования / декодирования потому что он будет закодирован как {{&lt;!-- TOKEN --&gt;how}} и, таким образом, полностью перевернут.

...