如何从字符串中删除换行符和空行

acruukt9  于 2021-05-31  发布在  Hadoop
关注(0)|答案(2)|浏览(491)

我试图在hadoop上运行mapreduce作业,读取制表符分隔文件的第五个条目(第五个条目是用户评论),然后对它们进行一些情绪分析和字数统计。
但是,正如您所知,用户评论通常包括换行符和空行。我的代码遍历每个评论的单词来查找关键字,并检查是否找到关键字。
问题是,当代码在评审中迭代时,它会给我 ArrayIndexOutofBoundsException 由于一次审阅中出现这些换行符和空行而导致的错误。
我试过使用 replaceAll("\r", " ") 以及 replaceAll("\n", " ") 无济于事。
我也试过了 if(tokenizer.countTokens() == 2){ word.set(tokenizer.nextToken());} else { } 也无济于事。下面是我的代码:

public class KWSentiment_Mapper extends Mapper<LongWritable, Text, Text, IntWritable> {
ArrayList<String> keywordsList = new ArrayList<String>();
ArrayList<String> posWordsList = new ArrayList<String>();
ArrayList<String> tokensList = new ArrayList<String>();
int e;

@Override
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {

    String[] line = value.toString().split("\t");
    String Review = line[4].replaceAll("[\\-\\+\\\\)\\.\\(\"\\{\\$\\^:,]", "").toLowerCase();

    StringTokenizer tokenizer = new StringTokenizer(Review);

    while (tokenizer.hasMoreTokens()) {
        // 1- first read the review line and store the tokens in an arraylist, 2-
        // iterate through review to check for KW if found
        // 3-check if there's PosWord near (upto +3 and -2)
        // 4- setWord & context.write 5- null the review line arraylist
        String CompareString = tokenizer.nextToken();

        tokensList.add(CompareString);
    }
    {
    for (int i = 0; i < tokensList.size(); i++)

    {

        for (int j = 0; j < keywordsList.size(); j++) {
            boolean flag = false;

            if (tokensList.get(i).startsWith(keywordsList.get(j)) == true) {

                for (int e = Math.max(0, i - 2); e < Math.min(tokensList.size(), i + 4); e++) {

                    if (posWordsList.contains(tokensList.get(e))) {

                        word.set(keywordsList.get(j));
                        context.write(word, one);
                        flag = true;

                        break; // breaks out of e loop }}
                    }
                }
            }
            if (flag)
                break;
        }
    }
    tokensList.clear();
}

}
预期结果如下:以发生错误的两个评审案例为例:
案例一:“漂亮宽敞!
我强烈推荐这个地方和伟大的主人。”
案例2:“一般来说,这个地方真的很安静,但我们没有被留下来的感觉。
除此之外,浴室很大,淋浴也很好,但也有问题。”
系统应该将整个评论作为一行来阅读,并遍历其中的单词。但是,它在发现换行符或空行时停止,如案例2所示。
案例1应该是这样的:“美丽而宽敞!我强烈推荐这个地方和伟大的主人。”
第二种情况应该是:“一般来说,这个地方真的很安静,但我们没有被留下来的感觉。除此之外,浴室很大,淋浴也很好,但也有问题。”
我的时间不多了,非常感谢您的帮助。
谢谢!

2o7dmzc5

2o7dmzc51#

所以,我希望我能理解你的意图。。。。如果我正确地阅读了上面的内容,那么传递到上面map函数中的'value'的值包含您想要解析用户评论的分隔值。如果是这样的话,我相信我们可以利用opencsv库中的转义功能,使用制表符作为分隔符而不是逗号来正确填充用户评论字段:http://opencsv.sourceforge.net
在本例中,我们从传入的输入中读取一行,并根据制表符将其解析为“columns”,然后将结果放入“nextline”数组。这将允许我们在不读取实际文件的情况下使用csvreader的转义功能,而使用传递到map函数中的文本值。

StringReader reader = new StringReader(value.toString());
        CSVReader csvReader = new CSVReader(reader, '\t', '\"', '\\', 0);

        String [] nextLine = csvReader.readNext();
        if(nextLine != null && nextLine.length >= 5) {
           // Do some stuff
        }

在上面粘贴的示例中,我认为即使拆分(“\n”)也是有问题的,因为用户审阅中的选项卡除了新行被视为新记录外,还拆分为结果中的两个结果。但是,这两个字符都是合法的,只要它们在引号内(因为它们应该在正确转义的文件中,并且在您的示例中也是如此)。csvreader应该处理所有这些。

vjrehmav

vjrehmav2#

在开始时验证每一行 map 方法,让你知道 line[4] 存在且不为空。

if (value == null || value.toString == null) {
    return;
}

String[] line = value.toString().split("\t");
if (line == null || line.length() < 5 || line[4] == null) {
    return;
}

至于换行符,您需要显示一些示例输入。默认情况下,mapreduce将每一行传递到 map 方法,因此如果确实希望将多行作为一条消息读取,则必须编写一个自定义的 InputSplit ,或预先格式化数据,以便每次审阅的所有数据都在同一行上。

相关问题