18

スコットランド語とウェールズ語のアクセント付きの地名 (グレイブ、アキュート、サーカムフレックス、ダイアレスを組み合わせたもの) が多数あり、それらを Unicode 正規化形式に更新する必要があります。たとえば、á0061 + 0301 ( \x61\x301)

pl/python を使用して、2009 年からの古い Postgres nabble メールリストから解決策を見つけました。

create or replace function unicode_normalize(str text) returns text as $$
  import unicodedata
  return unicodedata.normalize('NFC', str.decode('UTF-8'))
$$ LANGUAGE PLPYTHONU;

これは期待どおりに機能しますが、組み込みの Postgres 関数を使用して直接実行する方法があるかどうか疑問に思いました。convert_to を使用してさまざまな変換を試みましたが、すべて無駄でした。

編集:クレイグが指摘したように、私が試したことの1つ:

SELECT convert_to(E'\u00E1', 'iso-8859-1');

を返しますが\xe1

SELECT convert_to(E'\u0061\u0301', 'iso-8859-1');

で失敗しますERROR: character 0xcc81 of encoding "UTF8" has no equivalent in "LATIN1"

4

1 に答える 1

13

これは Pg のバグだと思います。

私の意見では、PostgreSQL は、エンコード変換を実行する前に、utf-8 を事前に構成された形式に正規化する必要があります。表示された変換の結果は間違っています。

私はpgsql-bugsでそれを上げます...完了。

http://www.postgresql.org/message-id/53E179E1.3060404@2ndquadrant.com

そこのスレッドをたどることができるはずです。

編集: pgsql-hackers は同意していないようです。アプリケーションの入力境界で UTF-8 を正規化することを強くお勧めします。

ところで、これは次のように簡略化できます。

regress=> SELECT 'á' = 'á';
 ?column? 
----------
 f
(1 row)

これは単なるクレイジーな話ですが、許可されています。1 つ目は構成済みで、2 つ目はそうではありません。(この結果を表示するには、コピーして貼り付ける必要があります。これは、ブラウザーまたは端末が utf-8 を正規化していない場合にのみ機能します)。

Firefox を使用している場合、上記が正しく表示されない場合があります。Chrome は正しくレンダリングします。ブラウザが分解された Unicode を正しく処理する場合、次のように表示されます。

分解されたユニコードと合成済みのユニコードの比較

于 2014-08-06T00:03:24.900 に答える