是PHP str
我想在UTF-8字符串上使用str_word_count()
。
这在PHP中安全吗? 在我看来,它应该是(特别是考虑到没有mb_str_word_count()
)。
但在php.net上,有很多人通过展示他们自己的'多字节兼容'版本的功能来混淆水。
所以我想我想知道...
鉴于str_word_count
只是简单地计算所有由" "
(空格)分隔的字符序列,所以对多字节字符串应该是安全的,即使它不一定知道字符序列,对吧?
UTF-8中是否有任何等效的“空格”字符,它们不是ASCII " "
(空格)?#
我猜这就是问题所在。
我会说你猜对了。 实际上UTF-8中有空格字符,它们不是US-ASCII的一部分。 给你一个这样的空间的例子:
也许还有:
无论如何,第一个 - 'NO-BREAK SPACE'(U + 00A0) - 就是一个很好的例子,因为它也是Latin-X字符集的一部分。 而且PHP手册已经提供了一个提示,即str_word_count
将取决于语言环境。
如果我们想要把它作为一个测试,我们可以设置语言环境为UTF-8,传递一个包含xA0
序列的无效字符串,如果这仍然算作断字符,那么该函数显然不是UTF-8安全的,因此不是多字节安全的(如同每个问题一样没有定义):
<?php
/**
* is PHP str_word_count() multibyte safe?
* @link https://stackoverflow.com/q/8290537/367456
*/
echo 'New Locale: ', setlocale(LC_ALL, 'en_US.utf8'), "nn";
$test = "awordxA0bword aword";
$result = str_word_count($test, 2);
var_dump($result);
输出:
New Locale: en_US.utf8
array(3) {
[0]=>
string(5) "aword"
[6]=>
string(5) "bword"
[12]=>
string(5) "aword"
}
正如本演示所示,该函数完全失败了它在手册页上给出的语言环境承诺(我不奇怪也不会呻吟),大多数情况下,如果您阅读某个函数是PHP中的语言环境特定的,运行您的生活并找到一个这不是)我在这里利用它来证明它绝不会对UTF-8字符编码做任何事情。
相反,对于UTF-8,您应该查看PCRE扩展:
PCRE对PHP中的Unicode和UTF-8具有很好的理解。 如果您仔细制作正则表达式模式,它也可以相当快。
关于“模板答案” - 我不明白需求“工作得更快”。 我们不是在讨论很长一段时间或很多次数,所以谁在乎是否需要几毫秒的时间呢?
但是,使用软连字符的str_word_count:
function my_word_count($str) {
return str_word_count(str_replace("xC2xAD",'', $str));
}
一个符合断言的函数(但可能不会比str_word_count更快):
function my_word_count($str) {
$mystr = str_replace("xC2xAD",'', $str); // soft hyphen encoded in UTF-8
return preg_match_all('~[p{L}'-]+~u', $mystr); // regex expecting UTF-8
}
preg函数与已经提出的基本相同,除了a)它已经返回一个计数,所以不需要提供匹配,这应该使它更快,并且b)实际上不应该是iconv后备,IMO。
关于评论:
我可以看到,你的PCRE函数比我的preg_word_count()要慢(性能),因为需要一个你不需要的str_replace:'〜[^ p {L} ' - xC2 xAD] +〜'' !)。
我认为一个不同的东西,字符串替换只会删除多字节字符,但你的正则表达式将以它们可能出现的任何顺序处理xC2
和xAD
,这是错误的。 考虑一个注册的标志,它是 xC2 xAE。
然而,现在我认为由于有效的UTF-8工作方式,这并不重要,所以应该同样适用。 所以我们可以拥有这个功能
function my_word_count($str) {
return preg_match_all('~[p{L}'-xC2xAD]+~u', $str); // regex expecting UTF-8
}
不需要任何匹配或其他替换。
关于str_word_count(str_replace(“ xC2 xAD”,'',$ str));如果用UTF8稳定,很好,但似乎不是。
如果你阅读这个线程,你会知道str_replace是安全的,如果你坚持有效的UTF-8字符串。 我没有看到任何相反的证据。
EDITED(显示新的线索):在PHP v5.1中使用str_word_count()
有一个可能的解决方案!
function my_word_count($str, $myLangChars="àáãâçêéíîóõôúÀÁÃÂÇÊÉÍÎÓÕÔÚ") {
return str_word_count($str, 0, $myLangChars);
}
但不是100%,因为我尝试添加到$ myLangChars xC2xAD
(SHY - SOFT HYPHEN字符),它必须是任何语言的单词组件,并且不起作用 (请参阅参考资料)。
另一个不是很快,而是基于PCRE库的完整而灵活的解决方案(从这里提取),但是可以选择模仿无效的UTF8上的str_word_count()
行为:
/**
* Like str_word_count() but showing how preg can do the same.
* This function is most flexible but not faster than str_word_count.
* @param $wRgx the "word regular expression" as defined by user.
* @param $triggError changes behaviour causing error event.
* @param $OnBadUtfTryAgain when true mimic the str_word_count behaviour.
* @return 0 or positive integer as word-count, negative as PCRE error.
*/
function preg_word_count($s,$wRgx='/[-'p{L}xC2xAD]+/u', $triggError=true,
$OnBadUtfTryAgain=true) {
if ( preg_match_all($wRgx,$s,$m) !== false )
return count($m[0]);
else {
$lastError = preg_last_error();
$chkUtf8 = ($lastError==PREG_BAD_UTF8_ERROR);
if ($OnBadUtfTryAgain && $chkUtf8)
return preg_word_count(
iconv('CP1252','UTF-8',$s), $wRgx, $triggError, false
);
elseif ($triggError) trigger_error(
$chkUtf8? 'non-UTF8 input!': "error PCRE_code-$lastError",
E_USER_NOTICE
);
return -$lastError;
}
}
(模板答案)帮助赏金!
(这不是答案,是对赏金的帮助,因为我不能编辑以复制问题)
我们希望以UTF-8最新文本来计算“真实世界的词汇”。
对于BOUNTY,我们需要:
assert
并比str_word_count
更快的str_word_count
; str_word_count
使用SHY字符(如何?); preg_word_count
工作更快(使用preg_replace?分词正则表达式?)。 ASSERTS
假设存在“多字节安全”函数my_word_count()
,则以下断言必须为真:
assert_options(ASSERT_ACTIVE, 1);
$text = "1,2,3,4=0 (1 2 3 4)=0 (... ,.)=0 (2.5±0.1; 0.5±0.2)=0";
assert( my_word_count($text)==0 ); // no word there
$text = "(one two,three;four)=4 (five-six sexC2xADven)=2";
assert( my_word_count($text)==6 ); // hyphen merges two words
$text = "(um±dois três)=3 (àáãâçêéíîóõôúÀÁÃÂÇÊÉÍÎÓÕÔÚ)=1";
assert( my_word_count($text)==4 ); // a UTF8 case
$text = "(ÍSÔ9000-X, ISÔ 9000-X, ÍSÔ-9000-X)=6"; //Codes are words?
assert( my_word_count($text)==6 ); // suppose no: X is another word
链接地址: http://www.djcxy.com/p/10175.html
上一篇: is PHP str
下一篇: How can I monitor and get http traffic in an android application?