Java简单句子解析器

3

有没有一种简单的方法在纯Java中创建句子解析器,而不需要添加任何库和jar文件。

解析器不仅应该处理单词之间的空格,还应该更加智能地解析:. ! ?,并识别句子何时结束等。

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

非常感谢您提前的帮助 :)


还要考虑 StreamTokenizer;它速度快,且可以灵活处理空格。 - trashgod
5个回答

8
你可能需要从BreakIterator类开始查找。
来自JavaDoc的信息。

BreakIterator类实现了用于查找文本边界位置的方法。 BreakIterator的实例保持当前位置并扫描文本,返回边界出现的字符的索引。在内部,BreakIterator使用CharacterIterator扫描文本,因此能够扫描由实现该协议的任何对象持有的文本。StringCharacterIterator用于扫描传递给setText的String对象。

您可以使用此类提供的工厂方法创建各种类型的分隔符迭代器的实例。特别是,使用getWordIterator、getLineIterator、getSentenceIterator和getCharacterIterator创建执行单词、行、句子和字符边界分析的BreakIterators。单个BreakIterator只能处理一个单位(单词、行、句子等)。您必须为要执行的每个单位边界分析使用不同的迭代器。

行边界分析确定文本字符串在换行时可以断开的位置。该机制正确处理标点符号和连字词。

句子边界分析允许选择带有数字和缩写中的句点以及引号和括号等尾随标点符号的正确解释。

单词边界分析用于搜索和替换功能,以及允许用户双击选择单词的文本编辑应用程序。单词选择提供了对单词内部和后续标点符号的正确解释。不属于单词的字符,例如符号或标点符号,在两侧都有单词分隔符。

字符边界分析允许用户按照他们所期望的方式与字符交互,例如在文本字符串中移动光标时。字符边界分析提供了正确的导航,无论字符如何存储。例如,一个带重音符号的字符可以被存储为基本字符和变音符号。用户认为是字符的内容可能因语言而异。

BreakIterator仅适用于自然语言。请勿使用此类对编程语言进行标记化。

查看演示BreakIteratorDemo.java


4

根据@Jarrod Roberson的回答,我创建了一个使用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;
}

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 );
            }

        }
    }
}

如果您有一个十进制数,它可能无法正确地进行处理。 - user177800

0

只需使用正则表达式 (\s+ - 它将应用于一个或多个空格、制表符等空白字符) 将字符串拆分为数组。

然后,您可以迭代该数组并检查单词是否以 .?! 结尾 (使用 String.endsWith() 找到句子的结尾)。

在保存任何单词之前,请再次使用正则表达式删除每个非字母数字字符。


10
有些人遇到问题时会想,“我知道,我可以使用正则表达式。”现在他们有了两个问题。 - Holograham

-2

如果您有一个十进制数,它可能无法正确地进行处理。 - user177800
2
同样适用于缩写,如Dr.或U.S.A. - gonzobrains

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接