10

たとえば、ブログ ソフトウェアを作成していて、エントリに付けられたコメントの数を表示したいとします。あなたはこのようにするかもしれません:

[Entry title]
[Content........]
[ <?php print($numComments;) ?> Comments]

次のような結果になる可能性があります。

[Entry title]
[Content........]
5 Comments

しかし、エントリにコメントが 1 つしかない場合は、その行に「コメント」ではなく「コメント」と表示する必要があります。そして in-lineif/elseは醜くて反復的です。

これに対処する最善の方法は何ですか?

4

7 に答える 7

13

ngettextこのような場合はこの機能をご利用ください。これにより、英語やその他の言語の複数形を一度に正しく処理できます。次のように使用します。

printf(ngettext("%d Comment", "%d Comments", $numComments), $numComments);

このngettext関数は"%d Comment"、コメントが1つしかない場合は最初のフォーマット文字列()を返し、"%d Comments"それ以上ある場合は2番目のフォーマット文字列()を返します。次に、printf関数は数値を文字列に入れます。

これは大変な作業のように思えるかもしれませんが、非常に強力です。複数形(!)が複数ある言語で機能します。実際に存在します。PHPのマニュアルには、私が認識できないエキゾチックな言語で「1 okno」、「2 okna」、「5oken」になる「window」という単語の例が示されています。

を使用することになった場合ngettext、遠く離れた国からの将来のユーザーはあなたに非常に感謝するでしょう:-)

編集:コメントで示唆されているように、上記を行うための単一の関数があります:

function pluralize($num, $singleWord, $pluralWord) {
    return printf(ngettext($singleWord, $pluralWord, $num), $num);
}

デフォルトでは、xgettextこの新しい関数は認識されませんが、--keywordフラグを使用して追加できます。test.php与えられたファイル

echo ngettext("foo", "foos", 1);
echo pluralize(2, "bar", "bars");

あなたは文字列を抽出することができます

xgettext --keyword=pluralize:2,3 test.php 

結果のmessages.poファイルには、次のようなエントリが含まれます。

#: test.php:7
msgid "foo"
msgid_plural "foos"
msgstr[0] ""
msgstr[1] ""

#: test.php:8
msgid "bar"
msgid_plural "bars"
msgstr[0] ""
msgstr[1] ""

翻訳者は各複数形に記入し、メッセージカタログヘッダーに正しく形成された「複数形」の行を入力すると、すべての言語をサポートできるようになります。

于 2009-07-21T23:01:32.960 に答える
4

時間をかけてもっと人間味を出してみませんか…。

switch ($numComments)
{
    case 0:
        echo "Be the first to write a comment";
        break;
    case 1:
        echo "Just one comment so far";
        break;
    default:
        echo "There are $numComments comments";

}
于 2009-07-21T20:03:25.113 に答える
3

数値と単語を受け取り、両方を含む文字列を返す関数を作成します。数が1より大きい場合、「s」を追加します(または作成した辞書を参照します)。

于 2009-07-21T19:55:54.363 に答える
3

まだ誰もそれを提案していないことに驚きましたが、私が通常行っているのは、条件演算子を使用することです。

string commentWord = numComments != 1 ? "Comments" : "Comment"; 

注: もちろん、文字列はこのようにハード コードする必要はありませんが、数値のフォーマット プレースホルダーと共に格納されているリソース リポジトリから読み込んで、数値が最後に表示される言語を処理できるようにする必要があります (または途中で):

// should load "{0} Comments" or "{0} Comment" if we run in an English locale
string comments = string.Format(
        numComments != 1 ? GetResource("Comments") : GetResource("Comment"),
        numComments);
于 2009-07-21T22:43:20.190 に答える
2

最もエレガントではありませんが、「コメント」を出力するのが最も簡単です。

[Entry title]
[Content........]
1 Comment(s)
于 2009-07-21T19:57:25.593 に答える
2

C/C++ では、次のことができます。PHPでも同様のことができるかもしれません。

printf("%d %s\n", numComments, numComments == 1 ? "Comment" : "Comments");

以下も機能しますが\b、異なる実装では (バックスペース) が正しく処理されないという問題が発生する可能性があります。

printf("%d Comment%s\n", numComments, numComments == 1 ? " \b" : "s");

(null character) を使用\0して何も出力しない代わりに、実装でスペースを出力しました。

于 2012-09-06T21:16:24.223 に答える
0

Rails inflector モジュールを確認してください。これにより、この問題に対する優れた集中化された構成可能なソリューションが提供されます。

于 2009-09-13T06:49:02.607 に答える