Я хочу использовать str_word_count() в строке UTF-8. 
  Это безопасно в 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'), "\n\n"; $test = "aword\xA0bword 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 хорошо разбирается в Unicode и UTF-8 в PHP. Он также может быть довольно быстрым, если вы тщательно продутируете шаблон регулярного выражения.
Об «шаблоне ответа» – я не получаю требование «работать быстрее». Мы не говорим о долгих временах или о многом подсчетах, так что кому это нужно, если это займет несколько миллисекунд дольше или нет?
Однако str_word_count работает с мягким дефис:
 function my_word_count($str) { return str_word_count(str_replace("\xC2\xAD",'', $str)); } 
функция, которая соответствует утверждениям (но, вероятно, не быстрее str_word_count):
 function my_word_count($str) { $mystr = str_replace("\xC2\xAD",'', $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 являются wrost (производительность), чем мой preg_word_count (), потому что вам нужно str_replace, которое вам не нужно: '~ [^ \ p {L} \' – \ xC2 \ xAD] + ~ u работает отлично ( !).
  Я считал, что другая вещь , замените строку, удалит только многобайтовый символ, но ваше регулярное выражение будет иметь дело с \\xC2 и \\xAD в любом порядке, который может появиться, что неверно.  Рассмотрим зарегистрированный знак , который является \ xC2 \ xAE. 
Однако теперь, когда я думаю об этом из-за того, как работает действительный UTF-8, это не имеет большого значения, поэтому его следует использовать одинаково хорошо. Таким образом, мы можем просто иметь функцию
 function my_word_count($str) { return preg_match_all('~[\p{L}\'\-\xC2\xAD]+~u', $str); // regex expecting UTF-8 } 
без необходимости в матчах или других заменах.
О str_word_count (str_replace ("\ xC2 \ xAD", '', $ str)) ;, если он стабилен с UTF8, это хорошо, но, похоже, это не так .
Если вы прочитаете этот поток , вы узнаете, что str_replace безопасен, если вы придерживаетесь действительных строк UTF-8. Я не видел никаких доказательств в вашей ссылке об обратном.
  EDITED (чтобы показать новые подсказки): существует возможное решение с использованием str_word_count() с PHP v5.1! 
 function my_word_count($str, $myLangChars="àáãâçêéíîóõôúÀÁÃÂÇÊÉÍÎÓÕÔÚ") { return str_word_count($str, 0, $myLangChars); } 
  но не 100%, потому что я пытаюсь добавить в $ myLangChars \xC2\xAD ( символ SHY – SOFT HYPHEN ), который должен быть компонентом слова на любом языке, и он не работает ( см. ). 
  Другое, не очень быстрое, но полное и гибкое решение (извлеченное отсюда) , основанное на библиотеке PCRE, но с возможностью имитировать поведение str_word_count() для недействительных UTF8: 
  /** * 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}\xC2\xAD]+/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.
assert s ниже и быстрее, чем str_word_count ; str_word_count работающий с символом SHY (как?); preg_word_count работает быстрее (используя регулярное выражение word-separator preg_replace?).   Предположим, что существует функция « my_word_count() safe» 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 se\xC2\xADven)=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 
Все это подсчитывает количество пробелов или слов между ними. если вам интересно, вы можете просто сделать свою собственную функцию подсчета с помощью взрыва и подсчета.
В любое время, когда найден байт ascii, он разбивается и все на самом деле.