PHP で情報のフォーマット操作を学ぶ方法

醉折花枝作酒筹
リリース: 2023-03-11 07:54:01
転載
2285 人が閲覧しました

国際コンポーネントを学習する過程で、数値を標準形式、通貨、現地言語などに変換できる NumberFormatter の数値書式設定操作をすでに体験しました。今日は、情報の書式設定に特に使用される別のクラス MessageFormatter について学習します。主に文字列操作に使用されます。

PHP で情報のフォーマット操作を学ぶ方法

MessageFormatter も ICU 仕様に従っており、最下層は C での ICU 操作であるため、C 関連のコードの使用法には大きな違いはありません。

書式設定

// 格式化
$fmt = new MessageFormatter("zh_CN", "{0,number,integer} 只猴子在 {1,number,integer} 颗树上,每只树上有 {2,number} 只猴子");
echo $fmt->format([4560, 123, 4560 / 123]), PHP_EOL;
// 4,560 只猴子在 123 颗树上,每只树上有 37.073 只猴子

$fmt = new MessageFormatter("de", "{0,number,integer} Affen auf {1,number,integer} Bäumen sind {2,number} Affen pro Baum");
echo $fmt->format([4560, 123, 4560 / 123]), PHP_EOL;
// 4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum

echo MessageFormatter::formatMessage("zh_CN", "{0,number,integer} 只猴子在 {1,number,integer} 颗树上,每只树上有 {2,number} 只猴子", [4560, 123, 4560 / 123]), PHP_EOL;
// 4,560 只猴子在 123 颗树上,每只树上有 37.073 只猴子

echo MessageFormatter::formatMessage("de", "{0,number,integer} Affen auf {1,number,integer} Bäumen sind {2,number} Affen pro Baum", [4560, 123, 4560 / 123]), PHP_EOL;
// 4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum
ログイン後にコピー

わかりますか? PDO のプリコンパイル操作のプレースホルダーに似ています。 format() メソッドを呼び出した後、このメソッドのパラメーターでプレースホルダーの内容を置き換えることができます。

プレースホルダーで使用されるパラメーターのタイプと位置を指定できます。{パラメーターの添字、タイプ、拡張タイプ} これは、この情報データの書式設定のためのプレースホルダーのルール定義です。非常にシンプルに見えますが、実際にはさらに多くの機能があります。これについては後ほど説明します。

ただし、サポートされるのは数値、日付、およびテキスト フラグメント タイプのみであることに注意してください。記事の最後にある参考リンクに公式ドキュメントがあります。

MessageFormatter::formatMessage() この静的メソッドでは、インスタンスを作成して format() メソッドを呼び出す必要がなく、言語、プリペアド ステートメント、および置換パラメータを一度に指定できます。

Deformat (ルールに従ってパラメータ配列を取得)

はフォーマットできますが、もちろん、ステートメントルールに従って該当する文字列をデフォーマットして取得することもできますプレースホルダーに対応するパラメーターのリスト。

// 根据格式化规则反向获取规则参数
$fmt = new MessageFormatter('zh_CN', "{0,number,integer} 只猴子在 {1,number,integer} 颗树上,每只树上有 {2,number} 只猴子");
$res = $fmt->parse("4,560 只猴子在 123 树上,每只树上有 37.073 只猴子");
var_export($res); // false
echo "ERROR: " . $fmt->getErrorMessage() . " (" . $fmt->getErrorCode() . ")\n";
// ERROR: Parsing failed: U_MESSAGE_PARSE_ERROR (6)

$fmt = new MessageFormatter('en_US', "{0,number,integer} monkeys on {1,number,integer} trees make {2,number} monkeys per tree");
$res = $fmt->parse("4,560 monkeys on 123 trees make 37.073 monkeys per tree");
var_export($res);
// array (
//     0 => 4560,
//     1 => 123,
//     2 => 37.073,
//   )

$fmt = new MessageFormatter('de', "{0,number,integer} Affen auf {1,number,integer} Bäumen sind {2,number} Affen pro Baum");
$res = $fmt->parse("4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum");
var_export($res);
// array (
//     0 => 4560,
//     1 => 123,
//     2 => 37.073,
//   )

$fmt = MessageFormatter::parseMessage('de', "{0,number,integer} Affen auf {1,number,integer} Bäumen sind {2,number} Affen pro Baum", "4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum");
var_export($fmt);
// array (
//     0 => 4560,
//     1 => 123,
//     2 => 37.073,
//   )
ログイン後にコピー

インスタンス化された parse() メソッドを使用するか、静的メソッド MessageFormatter::parseMessage() を直接使用すると、このような操作を実現できます。

中国語ロケールである zh_CN の場合、この操作により問題が発生することに注意してください。 getErrorMessage() および getErrorCode() を通じてエラー メッセージとエラー コードを確認できます。中国語の場合、返されたエラー メッセージは解析が失敗したことを直接意味していることがわかります。

取得ルールの設定

インスタンス化されたオブジェクトで、ルール ステートメントを動的に変更することもできます。

// 设置获取规则
$fmt = new MessageFormatter("zh_CN", "{0, number} 猴子在 {1, number} 颗树上");
echo "默认规则: '" . $fmt->getPattern(), PHP_EOL; // 默认规则: '{0, number} 猴子在 {1, number} 颗树上'
echo "格式化结果:" . $fmt->format(array(123, 456)), PHP_EOL; // 格式化结果:123 猴子在 456 颗树上

$fmt->setPattern("{0, number} 颗树上有 {1, number} 猴子");
echo "新规则: '" . $fmt->getPattern(), PHP_EOL; // 新规则: '{0, number} 颗树上有 {1, number} 猴子'
echo "新规则格式化结果: " . $fmt->format(array(123, 456)), PHP_EOL; // 新规则格式化结果: 123 颗树上有 456 猴子
ログイン後にコピー

2 つの非常に単純なメソッドです。setPattern() は現在のインスタンス化に対応する書式設定ルールを設定するために使用され、getPattern() は現在のインスタンス化オブジェクトの書式設定ルールを取得および表示するために使用されます。新しいルールを設定すると、新しいルール ステートメントに従って format() または parse() が実行されます。

完全な書式設定の例

上で述べたように、数値に加えて、日付形式のプレースホルダーも使用できます。それを示してみましょう。

echo MessageFormatter::formatMessage('zh_CN', '今天是 {3, date, full},当前时间为 {3, time, ::Hms}, 我要准备开始 {0} 了,今天要和 {2,number,integer} 人见面,还不能忘了要交 {1,number,currency} 元的电费', ['上班', 35.33, 25, new DateTime()]), PHP_EOL;
// 今天是 2020年11月16日星期一,当前时间为 10:09:30, 我要准备开始 上班 了,今天要和 25 人见面,还不能忘了要交 ¥35.33 元的电费
ログイン後にコピー

このステートメントでは、指定するパラメータの順序は、ステートメント内でプレースホルダが表示される順序ではありません。これは効果がありません。対応する位置にパラメータ配列の添字を指定するだけで済みます。例: 最初の {3, date, full} は、パラメーター配列の 4 番目の要素 (0 から始まる) を指定します。

日付型と時刻型の両方を指定できます。もちろん、日付形式を指定することもできます。たとえば、2 番目のプレースホルダーには、現在の時、分、秒の情報のみが表示されます。

文字列情報の場合は、単純な {0} だけが必要です。文字列の場合、それほど多くの型設定は必要ありません。数値型は、前に説明した NumberFormatter で指定できる型と同様に、通貨やその他の型に直接書式設定できます。

この例を読んで、この MessageFormatter の威力を感じましたか?心配しないでください。さらに素晴らしい機能があります。

パラメータの内容に応じた複数表示

複数の場合、中国語の文法には実際にはそのような記述はありません。たとえば、1 匹の猫は猫、2 匹の猫は 2 匹の猫です。

echo MessageFormatter::formatMessage('en_US', 'I Have {0, plural, =0{no cat} =1{a cat} other{# cats}}', [0]),PHP_EOL; // I Have no cat
echo MessageFormatter::formatMessage('en_US', 'I Have {0, plural, =0{no cat} =1{a cat} other{# cats}}', [1]),PHP_EOL; // I Have a cat
echo MessageFormatter::formatMessage('en_US', 'I Have {0, plural, =0{no cat} =1{a cat} other{# cats}}', [2]),PHP_EOL; // I Have 2 cats
ログイン後にコピー

パラメータの型 plural は複数を意味しますが、実際には switch() ステートメントと考えることができます。数値

echo MessageFormatter::formatMessage('zh_CN', '我{0, plural, =0{没有猫} other{有 # 只猫}}', [0]),PHP_EOL; // 我没有猫
echo MessageFormatter::formatMessage('zh_CN', '我{0, plural, =0{没有猫} other{有 # 只猫}}', [1]),PHP_EOL; // 我有 1 只猫
echo MessageFormatter::formatMessage('zh_CN', '我{0, plural, =0{没有猫} other{有 # 只猫}}', [2]),PHP_EOL; // 我有 2 只猫
ログイン後にコピー

\# は、対応するパラメーター値の元の内容です。この一連の構文は、MessageFormatter クラスをより高いレベルに引き上げます。まずこの問題を見てみましょう:

echo MessageFormatter::formatMessage('en_US', 'I Have {0, plural, =0{no cat} =1{a cat} other{# cats}}', [-1]),PHP_EOL; // I Have -1 cats
ログイン後にコピー

パラメータが間違って渡されます、-1 cat は間違っていますね? それは問題ではありません、この問題を解決する他の方法があります。

選択条件ルール

// 选择表达式
echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [-1]),PHP_EOL; // I Have no cats
echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [0]),PHP_EOL; // I Have no cats
echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [1]),PHP_EOL; // I Have one cat
echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [2]),PHP_EOL; // I Have 2 cats
echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [10]),PHP_EOL; // I Have 10 cats
ログイン後にコピー

単語の選択から、これが選択関連の文法であることがわかります。次のパラメータは実際には間隔であり、<= 0 | 1 | >=2 の範囲内でどのコンテンツが使用されるかを表します。さらに、プレースホルダー ルールにはプレースホルダー シンボルを含めることもできます。

概要

目を見張るものがありました。記事の最初の 2 つの部分では特に驚くようなことはありませんが、結局のところ、普通の文字列の交換ができますが、後ろに行くにつれてどんどん面白くなります。

もちろん、関連するルール構文はもっとあるはずですが、これらの資料は非常に乏しく、PHP 公式ドキュメントにも ICU 公式ドキュメントにもあまり紹介されていません。

ですから私たちは、「そんなものがある」と知る前に、学んで理解するという姿勢を今でも貫いています。今後は、もっと興味深い情報を見つけてから共有し、学んでいきたいと思っています。また、それを使った友人たちに感想を残してもらえることを願っています」メッセージを送って一緒に話し合ってください!

推奨学習: php ビデオ チュートリアル

以上がPHP で情報のフォーマット操作を学ぶ方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
php
ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート