由于开源和对.net的喜爱,以及较好的分词效果,喜欢上了KTDicSeg。由于工作的原因,我不得不使用java,我们选择使用ictclass4j。

一开始就觉得中文分词很难,而自己的水平似乎有限,在这种想法的左右下,从来没有想过要真正的去认认真真的看一个中文分词的源代码,同样是工作的原因,我现在不得不认认真真的去研究下中文分词。首先我先说明下,不要期待我写出太高明的文章,园中有非常多的前辈,就当是一起进步一起学习吧。

在查阅了大量的文档后,初步对中文分词有一个初步认识。

1、首先是将文章进行拆分成句子。

2、将句子根据字典拆分成词。

3、根据字与词,词与词成词的几率,以及词语的使用频度等等因素确定一种或多种分词方案。

4、根据指定的规则或者方式选择一种分词方案。

其中将文章拆分成句子,应该是最简单的一部分。

ictclass4j和KTDicSeg的处理方式有一些不同,但是最终要实现的目标是一样的。

首先说说ictclass4j处理的方式,我感觉这样的处理方式算不上高明。

1、将字符串分割成一个个字的数组。

2、对生成的数组遍历,连接成新的字符串,当遇到“!,"。”等标点符号的时候,将连接成的字符串放入中间结果集。

3、当遍历完成后,那个中间结果集就是我们需要的结果。

而KTDicSeg处理方式来说就显得干脆简介,直接用了正则,非常方便就将文章分割成句。这里我决定使用正则来处理。

下面是我的程序,我使用的是java来写的,说实话java让我很郁闷,java中没有ref的关键词,搞的我很多时候有点束手无策,由于我是从C#转到java来的吧。

首先就是定义正则了 ,这里我直接套用的是KTDicSeg中的正则

private static final String PATTERNS ="[0-9\\d]+\\%|[0-9\\d]{1,2}月|[0-9\\d]{1,2}日|[0-9\\d]{1,4}年|[0-9\\d]{1,4}-[0-9\\d]{1,2}-[0-9\\d]{1,2}|[0-9\\d]+|[^a-zA-Za-zA-Z0-90-9\u4e00-\u9fa5]|[a-zA-Za-zA-Z]+|[\u4e00-\u9fa5]+";

还有点很郁闷就是java中没有@关键字,反斜杠搞的我晕晕乎乎啊

下面的代码来应用这个正则:

publicArrayListSenSplit()

{if(Content.length()==0)

{returnnull;

}else{

ArrayListArraySen=newArrayList();

Pattern p=Pattern.compile(PATTERNS,Pattern.MULTILINE);

Matcher m=p.matcher(Content);while(m.find())

{intstart=m.start();intend=m.end();

ArraySen.add(Content.substring(start,end));

}returnArraySen;

}

}

而仅仅使用这个函数是不行的,因为会出现类似下面的情况:25.6 会被分成 25/./6 或者 suyuan19@gmail.com 会被分成 suyuan/19/@/gmail/./com 而我们实际想要结果可不是这样的,这就需要我们进行二次处理了。

首先是合并浮点数,合并email,合并英文关键词 比如 C# 等等,本篇文章中先不讨论英文关键词的问题。呵呵我感觉我是在讲解KTDicSeg了,不错,我们就是在模仿他,我甚至会做一些比较。

比如合并浮点数的问题:

Codeif(((word[0]>='0'&&word[0]<='9')||(word[0]>='0'&&word[0]<='9'))&&((word[word.Length-1]>='0'&&word[word.Length-1]<='9')||(word[word.Length-1]>='0'&&word[word.Length-1]<='9'))

)

{//合并浮点数word=MergeFloat(initSeg, i, ref i);

mergeOk=true;

这是KTDicSeg除非此类问题的条件。这里我提出不同的意见 比如文章中出现了 02343.25 之类的数字,那么最终合并的结果是 就是02343.25 而我个人认为这样是不正确的,我对这样的数字采取不处理的方式。同时我使用正则来解决这类问题。

Code//浮点数第一个数字不能为0Pattern p=Pattern.compile("[^0][0-9]+");if(p.matcher(reSen.get(index)).matches()&&(index+2)

{

index=MergeFloat(reSen,index);

if (index>=reSen.size())break;

同样合并的函数也是这样处理的:

/*** 合并浮点数

*@paramarr

*@paramindex*/publicintMergeFloat(ArrayListarr,intindex)

{//浮点数小数点后面允许以0开头Pattern p=Pattern.compile("[0-9]+");if(arr.get(index+1).equals(".")&&p.matcher(arr.get(index+2)).matches())

{result.add(new Sentence(arr.get(index)+arr.get(index+1)+arr.get(index+2),false));returnindex+3;

}else{returnindex;

}

}

下面来讨论合并email的函数,中间也大量的用到了正则:

由于email 必须是以字面开头 不能以数字或者_开通,但是email可以有数字或者是下划线 同时@符合后面可以是两段 如:126.com 也可以是三段,比如:126.com.cn 应该也是合法的.甚至是多段:

先看看我们的调用方法:

p=Pattern.compile("[a-z]+");//Email被初步分词后至少是4段长度if(p.matcher(reSen.get(index)).matches()&&(index+4)

{

index=MergeEmail(reSen,index);if(index>=reSen.size())break;

}

调用的时候,触发email合并的条件必须是英文字母开头.

下面是具体的Email合并函数:

/*** 合并Email

*@paramarr

*@paramindex*/publicintMergeEmail(ArrayListarr,intindex)

{intc_index=index;

Pattern p=Pattern.compile("[0-9_]+");

String Email=arr.get(index);while(!arr.get(index+1).equals("@")&&p.matcher(arr.get(index+1)).matches()&&(index+1)

{

Email+=arr.get(index+1);

index++;

}if(arr.get(index+1).equals("@"))

{

Email+=arr.get(index+1);

index++;

}while(!arr.get(index+1).equals(".")&&p.matcher(arr.get(index+1)).matches()&&(index+1)

{

Email+=arr.get(index+1);

index++;

}if(arr.get(index+1).equals("."))

{

Email+=arr.get(index+1);

index++;

}

p=Pattern.compile("[a-z]+");while(!arr.get(index+1).equals(".")&&p.matcher(arr.get(index+1)).matches()&&(index+1)

{

Email+=arr.get(index+1);

index++;

}if(arr.get(index+1).equals(".")&&p.matcher(arr.get(index+2)).matches())

{

Email+=arr.get(index+1);

index++;while(!arr.get(index+1).equals(".")&&p.matcher(arr.get(index+1)).matches()&&(index+1)

{

Email+=arr.get(index+1);

index++;

}

}

p=Pattern.compile("^([a-z0-9A-Z]+[-|\\_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$");if(p.matcher(Email).matches())

{

result.add(newSentence(Email,false));returnindex+1;

}else{returnc_index;

}

}

这个函数主要用正则对各个段进行判断,同时对生成的email的合法性进行判断,当合并的email是合法的才返回,否则回溯到原来的状态.用这样的判断方式就不会出现类型 suyuan/19/@/126/./com的情况了.

来看看我们写的这个分句函数的分句结果:

SentenceSeg SenSeg=newSentenceSeg(text);

ArrayListSenArray=SenSeg.getSenSeg();for(Sentence Sen : SenArray)

{

System.out.println(Sen.getContent()+Sen.isSeg());

}

上面是test的调用方式:

下面是分词结果:

Text: 一开始就觉得中文分词很难,而自己的水平似乎有限,25.632 suyuan@126.com

.在这种想法的左右下,从来没有想过要真正的去认认真真的看一个中文分词的源代码,同样是工作的原因,我现在不得不认认真真的去研究下中文分词。首先我先说明下,不要期待我写出太高明的文章,园中有非常多的前辈,就当是一起进步一起学习吧。

一开始就觉得中文分词很难true

,false

而自己的水平似乎有限true

,false

25.632false

false

suyuan@126.comfalse

.false

.false

.false

.false

在这种想法的左右下true

,false

从来没有想过要真正的去认认真真的看一个中文分词的源代码true

,false

同样是工作的原因true

,false

我现在不得不认认真真的去研究下中文分词true

。false

首先我先说明下true

,false

不要期待我写出太高明的文章true

,false

园中有非常多的前辈true

,false

就当是一起进步一起学习吧true

。false

基本符合了我预期的效果.那我们先讨论到这里,我会在后续时间里继续学习和改编中文分词.随着讨论的深入会越来越麻烦,希望自己可以最终进行下去.以上方法,未进行非常严格的测试,逻辑上面或许有不完善甚至错误的地方,希望大牛们能够给予指正

java以某个字符串断句_结合 ictclass4j 和 KTDictSeg 写自己的分词器----断句(1)相关推荐

  1. python实现自动断网_《自拍教程62》Python adb反复断网联网测试

    案例故事: Android App或者系统测试过程中,涉及需要断网异常测试(无网络情况下,App或系统是否提示正常,运行正常), 联网测试(网络恢复的情况下,App或系统是否提示正常,运行正常), 目 ...

  2. java两个字符串 相隔天数_关于Java: Joda-Time时间中两个日期之间的天数

    我如何找到两个joda time DateTime实例之间的天数差异?如果开始时间是星期一,结束时间是星期二,那么不管开始和结束日期的小时/分钟/秒是多少,返回值都应该是1. 如果从晚上开始到早上结束 ...

  3. java把abcedf字符串进行排序_字符串合并处理 - 一贱书生的个人空间 - OSCHINA - 中文开源技术交流社区...

    题目描述 按照指定规则对输入的字符串进行处理. 详细描述: 将输入的两个字符串合并. 对合并后的字符串进行排序,要求为:下标为奇数的字符和下标为偶数的字符分别从小到大排序.这里的下标意思是字符在字符串 ...

  4. java将表情字符串转表情符号_使用java将字符串中的表情符号替换为字符串

    如何从字符串中删除表情符号我的简单代码是.. public static void main(String[] args) throws SQLException { String str=" ...

  5. java腾讯字符串面试题_面试百度、阿里、腾讯,这134道Java面试题你会多少?

    这里一共是134道Java面试题,看看你能对几道吧! 1. Java 语言有哪些特点 2. 面向对象和面向过程的区别 3. 关于 JVM JDK 和 JRE 最详细通俗的解答 4. Oracle JD ...

  6. java时间转换为字符串格式错误_字符串转换为日期时间格式及其错误处理(转)

    1. 字符串转换成日期时间格式 //日期时间格式:yyyy-MM-dd hh:mm:ss String time ="1900-02-21 12:23:33"; //将字符串转换为 ...

  7. Java中布尔值的定义_使用简单的布尔值作为自定义验证器

    我正在Angular 4中尝试表单验证,我对实现自定义验证器有点困惑 . 这是我的表格组声明: this.signupForm = fb.group({ 'username': [null, Vali ...

  8. java仿qq空间音乐播放_使用JS改造的简单网页音乐播放器,仿QQ空间样式

    最近有好多东西要发表分享给大家,但由于时间问题,越多反而显得越乱,都不知道从何下手,该做的事情还有很多,最近整博客,又整得有点不兼容了,在想抽个时间修复它,可能时间要比较长,因为无从下手,必须一个一个 ...

  9. 中文分词器ICTCLAS使用方法(Java)

    http://www.cnblogs.com/CheeseZH/archive/2012/11/27/2791037.html 吃水不忘挖井人,这篇文章给了我很大帮助:http://blog.csdn ...

最新文章

  1. rust如何进枪战服_天龙八部怀旧服九大门派详细打造攻略——少林篇
  2. push_back()和emplace_back()函数
  3. 23 Merge k Sorted Lists
  4. 【机器学习PAI实践三】雾霾成因分析
  5. cad设计院常用字体_如何把CAD图纸坐标转换成现场坐标?
  6. java web.xml 监听器_【JAVA 核心技术】java web 中的监听器
  7. PHP用set_error_handler()拦截程序中的错误
  8. [洛谷P3292] [SCOI2016]幸运数字
  9. 探索pytest的fixture(上)
  10. modbus通讯协议编程实例_三菱PLC CC-LINK通讯编程实例分享,看完你就会了
  11. ps高低频磨皮详细教学
  12. allow_pickle什么意思_in pickle是什么意思
  13. 黑马程序员MySQL视频操作代码-P79
  14. 笔记本电脑开机到登入页面扩展显示器和电脑突然黑屏很久才显示
  15. 解读区块链技术中的“不可能三角”
  16. Java+Swing+Mysql学生宿舍管理系统
  17. vue+echart图表数据切换
  18. 浙江大学mooc的数据结构_课后习题01-复杂度2 Maximum Subsequence Sum
  19. linux安装福昕PDF阅读器
  20. 快速读懂Depth-wise Convolution

热门文章

  1. elemtnui 表格如何修改某行文字颜色(elemtnui table 修改某行文字颜色)
  2. pip下载包报错ERROR: Could not find a version that satisfies the requirement xxxx==1.0.2 (from versions
  3. 同步异步+阻塞非阻塞-三述
  4. 排队论和对策论(博弈论)
  5. 快速制作一个chrome插件
  6. 用户登录和用户注册案例
  7. 仿照源码,手写一个自定义 Spring MVC 框架
  8. php校园学校宿舍管理系统 php毕业设计题目课题选题 php毕业设计项目作品源码(3)班主任和宿舍管理员功能
  9. [转载]一个程序员心态决定成败
  10. 如何计算根号之牛顿迭代法