HomeFeedRegex BBS

我爱正则表达式

关注正则表达式和搜索引擎

wordpress UTF8 中文字数统计插件

admin @ 2009-01-02 10:37 pm

最近想在博客中实现这样的功能:“本文字数XXX,继续阅读…”。在网上找了一款Word Count Plugin for WordPress,作者是 Murray Williams,可惜它只能统计英文单词数,却不能统计中文字数。我下载了源码,自己动手修改,实现了想要的功能。修改过程中涉及了PHP语言中如何使用正则表达式来匹配中文,于是我把过程写这在里。


该插件的核心部分是这样的:

function mtw_wordcount() {
	global $page, $pages;
	if ( !function_exists('str_word_count') ) {
		return str_word_count(strip_tags($pages[$page-1]));
	} else {
		return count(explode(" ",strip_tags($pages[$page-1])));
	}
}

看来,它并没有自己来数字数,还是调用PHP函数str_word_count实现的。查文档,找到它的官方文档,http://us2.php.net/str_word_count。它能统计字串中的英文单词数,按要求返回单词数目或单方数组。其原理是以默认或指定的分隔符来将字串分隔,再逐个统计。由于该函数对utf8无效,应该使用utf8版:str_word_count_utf8

英文的单词之间有空格等分隔符,中文的应该怎样统计呢?由于Wordpress的中文字符编码为utf8,我们就从utf8入手。根据以前我写过一篇文章《匹配中文的正则表达式》可知,在utf8中,匹配单个汉字的正则式是[\x80-\xff]{3}。这样一来,只要将中文的每一个单字视为一个英语单词来处理,那么统计出来的单词数量就应该是正确的。例如,

你好,世界。Hello world.

我的处理方法是,将所有的中文单字替换成两边带空格的英文字母a,即使用正则表达式:

$string = preg_replace('/[\x80-\xff]{3}/', ' a ', $string);

考虑到中文标点不计入总数,前边还应该有一条:

$string =  $string = preg_replace("/~|!|`|·|#|¥|%|…|—|
(|)|+|-|=|{|}|[|]|\\|||“|”|’|‘|;|:|《|》|〈|〉|、|?|。|,/",' ',$string);

此时运行程序,得到正确的结果:6。

wordpress UTF8 中文字数统计插件完整的PHP程序是:

<?php
load_plugin_textdomain('mtw-wordcount','wp-content/plugins/mtw-wordcount');
 
/*	Call this from inside "The Loop" (see WordPress documentation) to get
	a WordCount of the current posting. Function RETURNS the Word Count as
	a value, it does not automatically display (ie. 'echo') the value.
 */
 
    define("WORD_COUNT_MASK", "/\p{L}[\p{L}\p{Mn}\p{Pd}'\x{2019}]*/u");
 
    function str_word_count_utf8($string, $format = 0)
    {
        $string =  $string = preg_replace("/~|!|`|·|#|¥|%|…|—|(|)|+|-|=|{|}|[|]|\\|||“|”|’|‘|;|:|《|》|〈|〉|、|?|。|,/",' ',$string);
        $string = preg_replace('/[\x80-\xff]{3}/', ' a ', $string);
        switch ($format) {
        case 1:
            preg_match_all(WORD_COUNT_MASK, $string, $matches);
            return $matches[0];
        case 2:
            preg_match_all(WORD_COUNT_MASK, $string, $matches, PREG_OFFSET_CAPTURE);
            $result = array();
            foreach ($matches[0] as $match) {
                $result[$match[1]] = $match[0];
            }
            return $result;
        }
        return preg_match_all(WORD_COUNT_MASK, $string, $matches);
    }
 
 
function mtw_wordcount() {
	global $page, $pages;
	if ( function_exists('str_word_count_utf8') ) {
		return str_word_count_utf8(strip_tags($pages[$page-1]));
	} else {
		return count(explode(" ",strip_tags($pages[$page-1])));
	}
}
 
/*	Auxilliary method. In case you want to use this somewhere outside the
	loop, where the $page and $pages globals don't necessarily work. Pass
	the string you want counted instead.
*/
function mtw_string_wordcount($instring) {
	if ( function_exists('str_word_count_utf8') ) {
		return str_word_count_utf8(strip_tags($instring));
	} else {
		return count(explode(" ",strip_tags($instring)));
	}
}
?>

这样修改后,该插件就能在wp中正确统计中文字数。我的使用方法是:

<?php the_content("本文共计".mtw_wordcount().'字,已浏览'.the_views("",false).'次。 继续阅读... »'); ?>

其中的the_views("",false)部分是另一款插件WP-PostViews Plus实现的效果,不赘述。

, , ,

Permanent Link | Posted in: 教程

© 我爱正则表达式 Allrights reserved. | Theme: iPost 2.7.2 |Designed By iFire. | Powered by WP. | Entries (RSS) | Comments (RSS).