Android的BreakIterator将换行符视为句子分隔符

时间:2018-01-22 14:01:55

标签: java android breakiterator

我有一个unix文本文件,我想在我的Android应用程序中阅读并将其拆分为句子。但是我注意到BreakIterator将一些换行符视为句子分隔符。 我使用以下代码读取文件并将其拆分为senteces(仅出于演示目的输出第一个句子):

        File file = new File...
        String text = "";
        BreakIterator sentenceIterator = BreakIterator.getSentenceInstance(Locale.US);

    try {
        FileInputStream inputStream = new FileInputStream(file);

        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String line;
        StringBuilder stringBuilder = new StringBuilder();

        while ((line = bufferedReader.readLine()) != null) {
            stringBuilder.append(line);
            stringBuilder.append('\n');
        }

        inputStream.close();
        text = stringBuilder.toString();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    sentenceIterator.setText(text);
    int end = sentenceIterator.next();
    System.out.println(end);
    System.out.println(text.substring(0, end));

但是,如果我编译并运行Eclipse中的代码作为桌面应用程序,文本将被正确分割。我不明白为什么它在Android应用程序上不会这样做。

我尝试将文本文件转换为dos格式,我甚至尝试读取文件并保留原始换行符:

    Pattern pat = Pattern.compile(".*\\R|.+\\z");
    StringBuilder stringBuilder = new StringBuilder();
    try (Scanner in = new Scanner(file, "UTF-8")) {
        String line;
        while ((line = in.findWithinHorizon(pat, 0)) != null) {
            stringBuilder.append(line);
        }
        text = stringBuilder.toString();
        sentenceIterator.setText(text);
        int end = sentenceIterator.next();
        System.out.println(end);
        System.out.println(text.substring(0, end));
    }

但没有成功。有任何想法吗? 您可以在此处下载文件摘录(unix格式):http://dropmefiles.com/TZgBp

我刚刚注意到它可以在不下载此文件的情况下进行复制。只需创建一个在句子中包含换行符的字符串(例如"Hello, \nworld!")并运行一个检测测试。如果在通常的测试中使用BreakIterator,那么它会正确分割。

我期待2句话:

句子1:

  

前言

     

如果一位同事今天晚上告诉你我的配偶   在家里制作不寻常的饭菜。

句子2:

  

你会加入吗?

是的,它们看起来不太好但至少你知道为什么会这样(句子分隔符是什么?等等)。但如果代码在Android上运行,它甚至会从

创建一个句子
  

前言

由于某种原因......

我不确定它是否是一个错误,或者是否有解决方法。但在我看来它使得BreakIterator的Android版本作为句子分割器没用,因为书籍中的句子分布在多行中是正常的。

在所有实验中,我使用了相同的import java.text.BreakIterator;

1 个答案:

答案 0 :(得分:1)

这不是一个真正的答案,但它可能会给你一些见解。

这不是文件编码问题,我按照他的方式尝试并且具有相同的错误行为。

BreakIterator sentenceIterator = BreakIterator.getSentenceInstance(Locale.US);
String text = "Foreword\nIf a colleague were to say to you, Spouse of me this night today manufactures the unusual meal in a home. You will join?";
sentenceIterator.setText(text);

Android不使用与您的计算机相同的Java版本

我注意到当我打印出sentenceIterator对象的类时

sentenceIterator.getClass()

使用IntelliJ运行时以及在Android上运行时,我有不同的类:

使用IntelliJ运行:

sun.util.locale.provider.RuleBasedBreakIterator

在Android上运行:

java.text.RuleBasedBreakIterator 

sun.util.locale.provider.RuleBasedBreakIterator有你想要的行为。

我不知道如何让Android使用好的RuleBasedBreakIterator类。我甚至不知道是否有可能。