Как закодировать амперсанд, если он еще не закодирован? - PullRequest
8 голосов
/ 11 октября 2011

Мне нужен метод c # для кодирования амперсандов, если они еще не закодированы или являются частью другого закодированного выражения

например

"tom & jill" should become "tom & jill"


"tom & jill" should remain "tom & jill"


"tom € jill" should remain "tom € jill"


"tom <&> jill" should become "tom <&amp;> jill"


"tom &quot;&&quot; jill" should become "tom &quot;&amp;&quot; jill"

Ответы [ 3 ]

11 голосов
/ 11 октября 2011

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

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

Теперь, если вы не уверены, закодирована ли строка или нет - проблема, скорее всего, будет не в самой строке, а в экосистеме, которая ее вызвала. Откуда ты это взял? Через кого он прошел, прежде чем до тебя дошло? Вы в это верите?

Если вам действительно придется прибегнуть к созданию функции magic-fix-weird-data, подумайте о создании таблицы "кодировок" и соответствующих им символов:

&amp; -> &
&euro; -> €
&lt; -> <
// etc.

Затем сначала декодирует все встречающиеся кодировки в соответствии с таблицей, а затем перекодирует всю строку. Конечно, вы могли бы получить более эффективные методы, когда шарить без предварительного декодирования. Но ты не будешь в здравом уме в следующем году. И это ваш перевозчик, верно? Вам нужно оставаться прямо в голове! Вы сойдете с ума, если попытаетесь быть слишком умным. И ты потеряешь свою работу, когда сойдешь с ума. Печальные вещи случаются с людьми, которые позволяют своим хакерам разрушать их умы ...

РЕДАКТИРОВАТЬ: Использование библиотеки .NET, конечно, спасет вас от безумия:

Я только что проверил это, и, похоже, нет проблем с декодированием строк с использованием только амперсандов в них. Итак, вперед:

string magic(string encodedOrNot)
{
    var decoded = HttpUtility.HtmlDecode(encodedOrNot);
    return HttpUtility.HtmlEncode(decoded);
}

EDIT # 2 : Оказывается, что декодер HttpUtility.HtmlDecode будет работать для вашей цели, но кодер не будет, так как вам не нужны угловые скобки (<, >) для кодирования. Но написать кодировщик действительно легко:

define encoder(string decoded):
    result is a string-builder
    for character in decoded:
        if character in encoding-table:
           result.append(encoding-table[character])
        else:
           result.append(character)
    return result as string
5 голосов
/ 11 октября 2011

Это должно сделать довольно хорошую работу:

text = Regex.Replace(text, @"
    # Match & that is not part of an HTML entity.
    &                  # Match literal &.
    (?!                # But only if it is NOT...
      \w+;             # an alphanumeric entity,
    | \#[0-9]+;        # or a decimal entity,
    | \#x[0-9A-F]+;    # or a hexadecimal entity.
    )                  # End negative lookahead.", 
    "&amp;",
    RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
1 голос
/ 11 октября 2011

с регулярным выражением это можно сделать с отрицательным lookahead .

&(?![^& ]+;)

тестовый пример здесь

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