当前位置: 首页 > 后端技术 > PHP

学习PHP中的信息格式化操作

时间:2023-03-29 14:05:03 PHP

在学习国际化组件的过程中,我们已经接触到了NumberFormatter这个数字格式化操作,可以让我们将数字转换成标准格式、货币、当地语言等形式。今天我们要学习的是另一个专门用于信息格式化的类MessageFormatter,主要是针对字符串的操作。MessageFormatter也遵循ICU规范,底层是C中的ICU操作,所以C相关代码的用法没有太大区别。Format//format$fmt=newMessageFormatter("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=newMessageFormatter("de","{0,number,integer}monkeyson{1,number,integer}treesare{2,number}monkeyspertree");echo$fmt->format([4560,123,4560/123]),PHP_EOL;//123棵树上的4,560只猴子是每棵37,073只猴子TreeechoMessageFormatter::formatMessage("zh_CN","{0,number,integer}只猴子在{1,number,integer}棵树上,每棵树有{2,number}只猴子",[4560,123,4560/123]),PHP_EOL;//4,560只猴子在123棵树上,每棵树有37,073只猴子echoMessageFormatter::formatMessage("de","{0,number,integer}猴子在{1,number,integer}树上是{2,number}monkeyspertree",[4560,123,4560/123]),PHP_EOL;//123棵树上的4,560只猴子是每棵树上的37,073只猴子,看到了吗?类似于PDO中预编译操作的占位符。调用format()方法后,可以使用该方法中的参数来替换占位符的内容。我们可以指定占位符使用的参数类型和位置,{parametersubscript,type,extensiontype}这是这个信息数据格式化的占位符的规则定义。看起来很简单,其实它还有更多的功能,后面我们会看到。不过需要注意的是,它只支持数字、日期和文本片段类型。文末参考链接中有官方文档。MessageFormatter::formatMessage()这个静态方法可以一次性指定语言、预运算语句和替换参数,不需要实例化再调用format()方法。反格式化(根据规则获取参数数组)即可格式化。当然,我们也可以根据语句规则对相关字符串进行格式化,得到占位符对应的参数列表。//根据格式化规则,反向获取规则参数$fmt=newMessageFormatter('zh_CN',"{0,number,integer}只猴子在{1,number,integer}棵树上,每棵树有{2,number}monkeys");$res=$fmt->parse("123棵树中有4,560只猴子,每棵树中有37.073只猴子");var_export($res);//falsecho“错误:”。$fmt->getErrorMessage()。"(".$fmt->getErrorCode().")\n";//错误:解析失败:U_MESSAGE_PARSE_ERROR(6)$fmt=newMessageFormatter('en_US',"{0,number,integer}monkeyson{1,number,integer}棵树每棵树生成{2,number}只猴子");$res=$fmt->parse("123棵树上的4,560只猴子每棵树生成37.073只猴子");var_export($res);//array(//0=>4560,//1=>123,//2=>37.073,//)$fmt=newMessageFormatter('de',"{0,number,integer}Affenauf{1,number,integer}B?umensind{2,number}AffenproBaum");$res=$fmt->parse("4.560Affenauf123B?umensind37,073AffenproBaum");var_export($res);//array(//0=>4560,//1=>123,//2=>37.073,//)$fmt=消息eFormatter::parseMessage('de',"{0,number,integer}Affenauf{1,number,integer}B?umensind{2,number}AffenproBaum","4.560Affenauf123B?umensind37,073AffenproBaum");var_export($fmt);//array(//0=>4560,//1=>123,//2=>37.073,//)实例化后使用parse()方法或直接使用静态方法MessageFormatter::parseMessage()可以实现这样的操作。需要注意的是,对于zh_CN,即中文语言环境,这个操作会出问题。通过getErrorMessage()和getErrorCode()可以看到错误信息和错误代码。可以看到对于中文,直接返回的错误信息是解析失败。设置获取规则在实例化的对象中,我们也可以动态修改规则语句。//设置获取规则$fmt=newMessageFormatter("zh_CN","{0,number}只猴子在{1,number}棵树上");回声“默认规则:'”。$fmt->getPattern(),PHP_EOL;//默认规则:'{0,number}只猴子在{1,number}棵树上'echo"Formatresult:".$fmt->format(array(123,456)),PHP_EOL;//格式化结果:123只猴子在456棵树上$fmt->setPattern("{1,number}只猴子在{0,number}棵树上");回声“新规则:'”。$fmt->getPattern(),PHP_EOL;//新规则:'在{0,number}棵树上有{1,number}只猴子'echo"Newruleformatsresults:".$fmt->format(array(123,456)),PHP_EOL;//新规则格式化结果:456monkeyson123trees有两个很简单的方法,setPattern()用于设置当前实例化对应的格式化规则,getPattern()用于获取和查看当前实例化对象格式化规则。设置新规则后,在执行format()或parse()时,按照新的规则语句执行。格式化一个完整的例子上面说了,除了数字,日期格式也可以有占位符,下面来演示一下。echoMessageFormatter::formatMessage('zh_CN','今天是{3,date,full},当前时间是{3,time,::Hms},我要开始{0}了,今天我会with{2,number,integer}人见面,别忘了交{1,number,currency}电费',['Gotowork',35.33,25,newDateTime()]),PHP_EOL;//今天是2020年11月16日星期一,当前时间是10:09:30,我要开始工作了,今天要和25个人开会,一定不要忘记交¥35.33的电费这句话中,parameters我们给的顺序不是占位符在语句中出现的顺序,所以是没有作用的。你只需要在相应的位置指定参数数组的下标即可。例如,first{3,date,full}指定参数数组中的第一个。4个元素(从0开始)。日期类型和时间类型都是可以指定的类型。当然,我们也可以指定它们的日期格式。例如,对于第二个占位符,我们只显示当前的小时、分钟和秒信息。如果是字符串信息,那么只需要一个简单的{0},字符串不需要过多的类型设置。数字类型可以直接格式化为货币等类型,就像我们之前讲的NumberFormatter中可以指定的那些类型一样。看完这个例子,是不是感受到了这个MessageFormatter的强大呢?别担心,它还有更强大的能力。根据参数内容显示复数对于复数,中文语法中没有这种说法,比如一只猫是一只猫,两只猫是两只猫。echoMessageFormatter::formatMessage('en_US','IHave{0,plural,=0{nocat}=1{acat}other{#cats}}',[0]),PHP_EOL;//IHavenocatechoMessageFormatter::formatMessage('en_US','IHave{0,plural,=0{nocat}=1{acat}other{#cats}}',[1]),PHP_EOL;//IhaveacatechoMessageFormatter::formatMessage('en_US','IHave{0,plural,=0{nocat}=1{acat}other{#cats}}',[2]),PHP_EOL;//IHave2虽然cats说参数类型的plural是复数的意思,其实我们可以看成是switch()语句的一种用法。echoMessageFormatter::formatMessage('zh_CN','I{0,plural,=0{nocats}other{have#cats}}',[0]),PHP_EOL;//我没有猫echoMessageFormatter::formatMessage('zh_CN','I{0,plural,=0{nocats}other{have#cats}}',[1]),PHP_EOL;//Ihave1catechoMessageFormatter::formatMessage('zh_CN','I{0,plural,=0{nocat}other{has#cats}}',[2]),PHP_EOL;//Ihave2cats\#是对应参数值的原始内容,这套语法让MessageFormatter类更上一层楼,还有什么!先来看看这个问题:echoMessageFormatter::formatMessage('en_US','IHave{0,plural,=0{nocat}=1{acat}other{#cats}}',[-1]),PHP_EOL;//IHave-1cats参数错误,-1cats错误,没关系,还有其他方法可以解决这个问题。选择条件规则//选择表达式echoMessageFormatter::formatMessage('en_US','IHave{0,choice,0#nocats|1#onecat|2#{0,number}cats}',[-1]),PHP_EOL;//我没有catsechoMessageFormatter::formatMessage('en_US','我有{0,choice,0#nocats|1#onecat|2#{0,number}cats}',[0]),PHP_EOL;//我没有catsechoMessageFormatter::formatMessage('en_US','我有{0,choice,0#nocats|1#onecat|2#{0,number}cats}',[1]),PHP_EOL;//IhaveonecatechoMessageFormatter::formatMessage('en_US','IHave{0,choice,0#nocats|1#onecat|2#{0,number}cats}',[2]),PHP_EOL;//我有2catsechoMessageFormatter::formatMessage('en_US','我有{0,choice,0#nocats|1#onecat|2#{0,number}cats}',[10]),PHP_EOL;//IHave10catschoice这个词可见,这是一个选择相关的语法。下面的参数其实是一个区间,代表在<=0|范围内使用哪些内容1|>=2。此外,可以在占位符规则中继续设置占位符符号。总结是另一个大开眼界。文章的前两部分实际上没有什么惊喜。毕竟普通的字符串替换是可以做到的,只是越往下越精彩。当然相关的规则语法应该比较多,但是这些资料很少,无论是PHP官方文档还是ICU官方文档都没有找到太多的介绍。所以,我们还是用学习和了解的态度,先知道是怎么回事。以后我们会发现更多有趣的信息,我们会分享和学习。也希望用过的朋友留言一起讨论!测试代码:参考文档:https://www.php.net/manual/zh/class.messageformatter.phphttp://userguide.icu-project.org/formatparse/messages===========各媒体平台均可搜索【硬核项目经理】