【问题标题】:Change special characters in array Delphi更改数组 Delphi 中的特殊字符
【发布时间】:2011-09-29 18:57:08
【问题描述】:

我得到的一些字符串是 UTF-8 编码的,并且包含一些特殊字符,例如 Å¡, Ä‘, Ä 等。我正在使用StringReplace() 将其转换为一些普通文本,但我只能转换一种类型的字符。因为 PHP 还有一个替换字符串的功能,如下所示:how to replace special characters with the ones they're based on in PHP?,但它支持数组:

<?php
  $vOriginalString = "¿Dónde está el niño que vive aquí? En el témpano o en el iglú. ÁFRICA, MÉXICO, ÍNDICE, CANCIÓN y NÚMERO.";

  $vSomeSpecialChars = array("á", "é", "í", "ó", "ú", "Á", "É", "Í", "Ó", "Ú", "ñ", "Ñ");
  $vReplacementChars = array("a", "e", "i", "o", "u", "A", "E", "I", "O", "U", "n", "N");

  $vReplacedString = str_replace($vSomeSpecialChars, $vReplacementChars, $vOriginalString);

  echo $vReplacedString; // outputs '¿Donde esta el nino que vive aqui? En el tempano o en el iglu. AFRICA, MEXICO, INDICE, CANCION y NUMERO.'
?>

如何在 Delphi 中做到这一点? StringReplace 不支持数组。

【问题讨论】:

  • 字符串是UTF-8编码的并且包含“特殊字符”?什么是“特殊字符”?也可以查看this answer——如果你可以访问iconv
  • 如果你想要这个进行比较,那么在dwCmpFlags中使用CompareString和至少NORM_IGNORENONSPACE

标签: arrays delphi unicode normalization unicode-normalization


【解决方案1】:

摆脱口音被称为Normalization

由于您使用的是 Unicode,您不仅希望规范化问题中的重音字符的简短列表。事实上,您正在寻找 Unicode Normalization Form D (NFD) 或 KD (NFKD),您可以在 Windows 和 Delphi 中执行这些操作。

This answer 应该让你在理论上继续前进。

This Delphi codethis answer 应该会让你开始实施。

【讨论】:

  • 这听起来像是正确的方法。我只是天真地回答了这个问题。
  • 抱歉,“摆脱重音”是不是规范化——它只是摆脱重音!规范化不会改变字符的语义,它只是以一致的方式在“base plus diacritic”和“legacy Latin-1”形式(以及其他一些适当的形式)之间进行选择,以便两个规范化的字符串比较相等,如果它们'在语义上是相等的。 OP 的目标似乎是音译到纯 ASCII 字符。
  • @Kerrek:我推断规范化是因为 OP 链接到提到规范化的 PHP 解决方案。
  • @Jeroen:即使链接接受的 SO 答案也是错误的,正如其 cmets 所指出的那样; PHP normalize function 完全符合 Unicode 标准和我所说的。它确实将ä音译为a!
  • @Jeroen:嗯,我更喜欢iconving 到 ASCII//TRANSLIT,然后正则表达式 \w 出来,我认为这更简单,更简单......
【解决方案2】:
function str_replace(const oldChars, newChars: array of Char; const str: string): string;
var
  i: Integer;
begin
  Assert(Length(oldChars)=Length(newChars));
  Result := str;
  for i := 0 to high(oldChars) do
    Result := StringReplace(Result, oldChars[i], newChars[i], [rfReplaceAll])
end;

如果您担心由StringReplace 引起的所有不必要的堆分配,那么您可以这样写:

function str_replace(const oldChars, newChars: array of Char; const str: string): string;
var
  i, j: Integer;
begin
  Assert(Length(oldChars)=Length(newChars));
  Result := str;
  for i := 1 to Length(Result) do
    for j := 0 to high(oldChars) do
      if Result[i]=oldChars[j] then
      begin
        Result[i] := newChars[j];
        break;
      end;
end;

这样称呼它:

newStr := str_replace(
  ['á','é','í'],
  ['a','e','i'], 
  oldStr
);

【讨论】:

猜你喜欢
  • 2021-08-19
  • 1970-01-01
  • 2021-08-18
  • 1970-01-01
  • 2015-12-31
  • 2014-02-16
  • 2016-02-09
  • 2021-06-09
  • 2013-07-21
相关资源
最近更新 更多