2010-01-20 67 views
2

是否有任何简单的方法在普通Java 中创建句子解析器而不添加任何库和罐子。Java简单句子解析器

解析器不应该只关注单词之间的空白, 但更聪明并且解析:。 ! ?, 识别句子何时结束等。

解析后,只有真实的单词可以全部存储在数据库或文件中,而不是任何特殊的字符。

非常感谢你的所有提前:)

+0

另请考虑['StreamTokenizer'](http://docs.oracle.com/javase/7/docs/api/java/io/StreamTokenizer.html);这是[快速](http://stackoverflow.com/a/2082174/230513),并容纳空白灵活。 – trashgod 2012-09-28 16:35:50

回答

7

你可能想通过查看BreakIterator类开始。

来自JavaDoc。

的的BreakIterator类实现 方法用于查找文本的 边界位置。 的实例BreakIterator维持当前的 位置并扫描文本返回 字符的索引,其中 边界发生。在内部, BreakIterator使用一个 CharacterIterator扫描文本,并因此能够执行该协议的任何对象 持有的扫描文本 。 A StringCharacterIterator用于 扫描传递给setText的String对象。

您可以使用此类提供的工厂方法 来创建各种类型的中断迭代器的实例 。在 特别是使用getWordIterator, getLineIterator,getSentenceIterator, 和getCharacterIterator创建 BreakIterators执行分别字, 行,句子和字符边界 分析。一个 BreakIterator只能在一个 单元(字,行,句子等 )上工作。对于您希望执行的每个单位边界分析,您必须使用不同的迭代器 。

线边界分析确定 其中当 换行时文本字符串可能被破坏。正确的机制 处理标点符号和连字符 单词。

句子边界分析允许 选择与数字和 缩写内周期的正确解释 ,和后 标点符号例如引号 标记和括号。

单词边界分析使用 搜索和文本编辑应用 ,允许用户选择通过双击的话 内更换功能以及 的。单词选择 提供 单词内部和之后的标点符号 的正确解释。不属于 一个单词的字符,如符号或标点符号 ,在双方都有分词符。

字符边界分析允许 用户与人物互动作为 他们希望,例如,当 通过文本 字符串移动光标。字符边界分析 提供了通过 字符串的正确导航,无论如何存储字符 。例如, 可能会将重音字符存储为 作为基本字符和变音符号 标记。用户认为是 字符的字符可以在 语言之间有所不同。

BreakIterator仅适用于 自然语言。不要使用 这个类来标记编程 语言。

见演示BreakIteratorDemo.java

-1

String Tokenizer

Scanner

例。

StringTokenizer tokenizer = new StringTokenizer(input, " !?."); 
+0

如果你有一个十进制数,它不会中断。 – 2011-05-13 14:46:30

+2

与Dr.或U.S.A这样的缩写相同 – gonzobrains 2013-02-27 06:58:43

1

只需使用正则表达式(\s+ - 这将适用于一个或更多个空白字符(空格,制表符,等)),以字符串分割成阵列。

然后你可以遍历数组,并检查字是否与.?!String.endsWith()找到句子的末尾结束。

并保存任何单词前使用一次正则表达式删除所有非字母数字字符。

+9

有些人遇到问题时会想:“我知道,我会用正则表达式。”现在他们有两个问题。 – Holograham 2010-01-20 18:01:45

0

当然,使用的StringTokenizer

import java.util.StringTokenizer; 

public class Token { 
    public static void main(String[] args) { 

     String sentence = "Java! simple ?sentence parser."; 
     String separator = "!?."; 

     StringTokenizer st = new StringTokenizer(sentence, separator, true); 

     while (st.hasMoreTokens()) { 
      String token = st.nextToken(); 
      if (token.length() == 1 && separator.indexOf(token.charAt(0)) >= 0) { 
       System.out.println("special char:" + token); 
      } 
      else { 
       System.out.println("word :" + token); 
      } 

     } 
    } 
} 
+0

如果你有一个十进制数,它将不会中断。 – 2011-05-13 14:45:40

3

基于@Jarrod Roberson's answer,我已经创建了一个使用的BreakIterator,返回语句列表一个实用程序方法。

public static List<String> tokenize(String text, String language, String country){ 
    List<String> sentences = new ArrayList<String>(); 
    Locale currentLocale = new Locale(language, country); 
    BreakIterator sentenceIterator = BreakIterator.getSentenceInstance(currentLocale);  
    sentenceIterator.setText(text); 
    int boundary = sentenceIterator.first(); 
    int lastBoundary = 0; 
    while (boundary != BreakIterator.DONE) { 
     boundary = sentenceIterator.next();   
     if(boundary != BreakIterator.DONE){ 
      sentences.add(text.substring(lastBoundary, boundary)); 
     } 
     lastBoundary = boundary;    
    } 
    return sentences; 
}