如何摆脱这些空字符串?

时间:2014-11-04 17:50:56

标签: java string bufferedreader

我的构造函数采用文本文件的文件名,并将其转换为小写的所有单词的ArrayList,没有标点符号或空格。这些规范以及构造函数的参数由我的作业指定,因此不建议我更改它们。

private ArrayList<String> list;

public Tokenizer(String file) throws IOException {
    list = new ArrayList<>();
    String thisLine;
    BufferedReader br = new BufferedReader(new FileReader(file));

    while ((thisLine = br.readLine()) != null)
        list.addAll(Arrays.asList(thisLine.replaceAll("\\p{Punct}+"," ").toLowerCase().split("\\s+")));
}

我的问题是出现了许多空字符串。我尝试过使用&#34; -1&#34;作为&#34; split&#34;中的第二个参数,但它似乎没有做任何事情。

我的另一个问题是它是否效率低Arrays.asList,或者我是否应该创建一个迭代器,如果你认为我做了其他任何错误的话。例如,是否有另一种方法将文件名输入BufferedReader

由于

编辑1:

下面是我用于在线书籍的测试(它是一个文本文件,文本文件没有问题)我在项目Gutenberg上找到了。使用我个人创建的文本文件时,我也会得到类似的结果,所以不要认为文本文件本身存在问题。

事实上,我只是重现了我的整个代码,因为它非常简单:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

public class Tokenizer {
    private ArrayList<String> list;

    public Tokenizer(String file) throws IOException {
        list = new ArrayList<>();
        String thisLine;
        BufferedReader br = new BufferedReader(new FileReader(file));

        while ((thisLine = br.readLine()) != null)
            list.addAll(Arrays.asList(thisLine.replaceAll("\\p{Punct}+"," ").toLowerCase().trim().split("\\s+")));
    }

    public ArrayList<String> wordList() {
        return list;
    }

    public static void main(String[] args) throws IOException {
        Tokenizer T = new Tokenizer("C:\\...\\1898amongmyb00loweuoft_djvu.txt");

        ArrayList<String> array = T.wordList();

        for(int i = 0; i < 20; i++) {
            System.out.println(array.get(i));
        }
    }
}

这是我的输出:

i
9



digitized
by
the
internet
archive

in
2007
with
funding
from

microsoft
corporation

不,那些空行不是空格。它们是空字符串。如同,&#34;&#34;。我希望我尽可能清楚。

因为它可能会引起混淆,所以这不是我用于文件路径名的实际参数。省略号(&#34; ...&#34;)只是一个简写,所以我不必将我的计算机目录显示到互联网上。

另外,是的,最后还有另一个空字符串,但这个网站的界面不允许我把它放在那里。

编辑2:

我总是忘记一些事情,这是文本文件的前几行:

I 9

通过互联网档案数字化

2007年,资金来自

Microsoft Corporation

http://www.archive.org/details/1898amongmyb00loweuoft

James Ettsscll Lotocll。

完整的诗歌和散文作品。河边 版本,n vols,皇冠8vo,镀金顶部,每个,1.50美元;集合, $ 1 6. 50.

1-4。文学论文(包括我的学习Windows,其中 我的书,炉边旅行); 5.政治论文; 6.文学 和政治地址; 7.最新的文学论文和广告 - 连衣裙,古英语剧作家; 8-1 1.诗歌。

PROSE WORKS。滨江版。随着肖像。 7卷, 皇冠8vo,镀金上衣,10.50美元。

POEMS。滨江版。随着肖像。 4卷,皇冠 8vo,镀金上衣,6.00美元。

完整的政治工作。剑桥版。 在透明的不透明纸上印刷,很有吸引力 界。使用肖像和雕刻标题页,和 洛厄尔的家,埃尔姆伍德的小插图。大皇冠8vo,$ 2.00。 家庭版。用肖像和插图。王冠 8vo,1.50美元。

橱柜版。 i8的

我想我现在看到了问题。空字符串对应于空行。

编辑3:

所以我最终回答了自己的问题。我最终这样做了:

while ((thisLine = br.readLine()) != null) {
        ArrayList<String> newList = new ArrayList(Arrays.asList(thisLine.replaceAll("\\p{Punct}+"," ").toLowerCase().split("\\s+")));
        while(newList.remove(""));     
        list.addAll(newList);
    }

我确实尝试使用if语句,但是你在分割之前比较了这一行。这可能会有问题,因为拆分可能会产生一些你会错过的空行。因此,我创建了我要添加到主列表中的列表,但在添加之前,我只是通过它并删除了所有空字符串的实例。

我真的不知道这是否是最有效的做事方式......如果不让我知道的话!

2 个答案:

答案 0 :(得分:0)

您的问题很可能是thisLine从文件中读取的开头或结尾有空格。对于具有这样的行的文本文档而言,这是很常见的。因此,如果您在\s+上调用split并且该行以空格结尾,则最后一项将是空字符串。

要解决此问题,我建议您在进行拆分之前在字符串上添加修剪。

使用您的代码将其更改为:

list.addAll(Arrays.asList(thisLine.replaceAll("\\p{Punct}+"," ").toLowerCase().trim().split("\\s+")));

尝试一下,看看它是否没有删除大多数(如果不是全部)空字符串。此外,您应该考虑将此语句分解为多个操作,以便更容易阅读。

答案 1 :(得分:0)

如何替换while ((thisLine = br.readLine()) != null) list.addAll(Arrays.asList(thisLine.replaceAll("\\p{Punct}+"," ").toLowerCase().trim().split("\\s+")));

with:while ((thisLine = br.readLine()) != null ) if (thisLine.length() > 0) list.addAll(Arrays.asList(thisLine.replaceAll("\\p{Punct}+", " ").toLowerCase().trim().split("\\s+")));