PHP中文分词的简单实现代码分享


Posted in PHP onJuly 17, 2011

当然, 本文不是要对中文搜索引擎做研究, 而是分享如果用 PHP 做一个站内搜索引擎。 本文是这个系统中的一篇。
我使用的分词工具是中科院计算所的开源版本的 ICTCLAS。 另外还有开源的 Bamboo, 我随后也会对该工具进行调研。
从 ICTCLAS 出发是个不错的选择, 因为其算法传播比较广泛, 有公开的学术文档, 并且编译简单, 库依赖少。 但目前只提供了 C/C++, Java 和 C# 版本的代码, 并没有 PHP 版本的代码。 怎么办呢? 也许可以学习它的 C/C++ 源码和学术文档中, 然后再开发一个 PHP 版本出来。 不过, 我要使用进程间通信, 在 PHP 代码里调用 C/C++ 版本的可执行文件。
下载源码解压后, 在有 C++ 开发库和编译环境的机器上直接 make ictclas 即可。 它的 Makefile 脚本有个错误, 执行测试的代码没有加上'。/', 当然不能像 Windows 下执行成功了。 但也不影响编译结果。
进行中文分词的 PHP 类就在下面了, 用 proc_open() 函数来执行分词程序, 并通过管道和其交互, 输入要进行分词的文本, 读取分词结果。

<?php 
class NLP{ 
private static $cmd_path; 
// 不以'/'结尾 
static function set_cmd_path($path){ 
self::$cmd_path = $path; 
} 
private function cmd($str){ 
$descriptorspec = array( 
0 => array("pipe", "r"), 
1 => array("pipe", "w"), 
); 
$cmd = self::$cmd_path . "/ictclas"; 
$process = proc_open($cmd, $descriptorspec, $pipes); 
if (is_resource($process)) { 
$str = iconv('utf-8', 'gbk', $str); 
fwrite($pipes[0], $str); 
$output = stream_get_contents($pipes[1]); 
fclose($pipes[0]); 
fclose($pipes[1]); 
$return_value = proc_close($process); 
} 
/* 
$cmd = "printf '$input' | " . self::$cmd_path . "/ictclas"; 
exec($cmd, $output, $ret); 
$output = join("\n", $output); 
*/ 
$output = trim($output); 
$output = iconv('gbk', 'utf-8', $output); 
return $output; 
} 
/** 
* 进行分词, 返回词语列表. 
*/ 
function tokenize($str){ 
$tokens = array(); 
$output = self::cmd($input); 
if($output){ 
$ps = preg_split('/\s+/', $output); 
foreach($ps as $p){ 
list($seg, $tag) = explode('/', $p); 
$item = array( 
'seg' => $seg, 
'tag' => $tag, 
); 
$tokens[] = $item; 
} 
} 
return $tokens; 
} 
} 
NLP::set_cmd_path(dirname(__FILE__)); 
?>

使用起来很简单(确保 ICTCLAS 编译后的可执行文件和词典在当前目录):
<?php 
require_once('NLP.php'); 
var_dump(NLP::tokenize('Hello, World!')); 
?>
PHP 相关文章推荐
PHP脚本数据库功能详解(中)
Oct 09 PHP
使用php shell命令合并图片的代码
Jun 23 PHP
PHP的几个常用数字判断函数代码
Apr 24 PHP
php利用腾讯ip分享计划获取地理位置示例分享
Jan 20 PHP
php判断字符串在另一个字符串位置的方法
Feb 27 PHP
php防止伪造的数据从URL提交方法
Jun 27 PHP
PHP+jQuery 注册模块的改进(三):更新到Smarty3.1
Oct 14 PHP
php通过curl模拟登陆DZ论坛
May 11 PHP
php判断用户是否关注微信公众号
Jul 22 PHP
PHP foreach遍历多维数组实现方式
Nov 16 PHP
php使用include 和require引入文件的区别
Feb 16 PHP
PHP registerXPathNamespace()函数讲解
Feb 03 PHP
PHP 删除文件与文件夹操作 unlink()与rmdir()这两个函数的使用
Jul 17 #PHP
从手册去理解分析PHP session机制
Jul 17 #PHP
php数组的一些常见操作汇总
Jul 17 #PHP
PHP在特殊字符前加斜杠的实现代码
Jul 17 #PHP
PHP的explode和implode的使用说明
Jul 17 #PHP
PHP冒泡排序算法代码详细解读
Jul 17 #PHP
MySQL连接数超过限制的解决方法
Jul 17 #PHP
You might like
php设计模式 Delegation(委托模式)
2011/06/26 PHP
Joomla实现组件中弹出一个模式(modal)窗口的方法
2016/05/04 PHP
PHP简单实现二维数组赋值与遍历功能示例
2017/10/19 PHP
js显示时间 js显示最后修改时间
2013/01/02 Javascript
上传图片预览JS脚本 Input file图片预览的实现示例
2014/10/23 Javascript
node.js中的fs.writeFile方法使用说明
2014/12/14 Javascript
使用VS开发 Node.js指南
2015/01/06 Javascript
jquery仿百度经验滑动切换浏览效果
2015/04/14 Javascript
Javascript中的getUTCDay()方法使用详解
2015/06/10 Javascript
jquery获取img的src值的简单实例
2016/05/17 Javascript
javascript cookie基础应用之记录用户名的方法
2016/09/20 Javascript
jQueryMobile之窗体长内容的缺陷与解决方法实例分析
2017/09/20 jQuery
基于vue2.0实现简单轮播图
2017/11/27 Javascript
jQuery与vue实现拖动验证码功能
2018/01/30 jQuery
vue中$refs的用法及作用详解
2018/04/24 Javascript
javascript实现5秒倒计时并跳转功能
2019/06/20 Javascript
Nuxt使用Vuex的方法示例
2019/09/06 Javascript
Node Mongoose用法详解【Mongoose使用、Schema、对象、model文档等】
2020/05/13 Javascript
解决ant Design中Select设置initialValue时的大坑
2020/10/29 Javascript
[56:48]FNATIC vs EG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
使用Python进行新浪微博的mid和url互相转换实例(10进制和62进制互算)
2014/04/25 Python
Python 序列的方法总结
2016/10/18 Python
Python实现嵌套列表去重方法示例
2017/12/28 Python
详解python中的json和字典dict
2018/06/22 Python
python模拟鼠标点击和键盘输入的操作
2019/08/04 Python
PyTorch中 tensor.detach() 和 tensor.data 的区别详解
2020/01/06 Python
Python selenium键盘鼠标事件实现过程详解
2020/07/28 Python
退休感言
2014/01/28 职场文书
车间核算员岗位职责
2014/07/01 职场文书
小学学习雷锋活动总结
2014/07/03 职场文书
承诺书范本
2015/01/21 职场文书
入党申请书怎么写?
2019/06/11 职场文书
表扬稿表扬信的格式及范文
2019/06/24 职场文书
JavaScript声明变量和数据类型的转换
2022/04/12 Javascript
SQL Server Agent 服务无法启动
2022/04/20 SQL Server
Android开发之底部导航栏的快速实现
2022/04/28 Java/Android