Как закодировать амперсанд, если он еще не закодирован?

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

например

"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 ответов


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

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);

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

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

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

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

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

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

EDIT: использование библиотеки .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

С regex это можно сделать с отрицательным lookahead.

&(?![^& ]+;)