如何从字符串

时间:2019-01-21 18:17:42

标签: java eclipse hadoop mapreduce line-breaks

我正在尝试在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();
}

}

预期结果如下: 考虑发生错误的以下两种情况:

案例1:“美丽而宽敞!
我强烈推荐这个地方和很棒的主人。”

案例2:“总的来说,这个地方真的很安静,但是我们没有留下来。

除此之外,浴室很大,淋浴真的很好,但是有问题。 “

系统应将整个评论读为一行,并反复浏览其中的单词。但是,它会在遇到情况2时找到换行符或空行后停止。
案例1应该读为:“美丽而宽敞!我强烈推荐这个地方,很棒的主人。”

第2种情况应该是:“总的来说,这个地方真的很安静,但我们没有感觉到停留。除此之外,浴室很大,淋浴真的很好,但是有问题。”

我的时间不多了,非常感谢您的帮助。

谢谢!

2 个答案:

答案 0 :(得分:0)

所以,我希望我能理解您要做什么。 如果我正确地读取了上面的内容,则传递到上面的map函数中的“值”的值包含您要从中解析出用户评论的定界值。如果是这种情况,我相信我们可以使用制表符作为分隔符(而不是逗号)来使用opencsv库中的转义功能来正确填充用户查看字段: http://opencsv.sourceforge.net

在此示例中,我们从传入的输入中读取一行,并基于制表符将其解析为“列”,并将结果放置在“ 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
        }

在您上面粘贴的示例中,我认为即使split(“ \ n”)也会出现问题,因为除了将新行视为新记录之外,用户评论中的选项卡还会分成两个结果。但是,只要这两个字符都位于带引号的值内(因为它们应该在正确转义的文件中,并且与您的示例中的一样),则这两个字符都是合法的。 CSVReader应该处理所有这些。

答案 1 :(得分:0)

ServerHttpSecurity方法的开头验证每一行,以使您知道map存在并且不为空。

line[4]

对于换行符,您需要显示一些示例输入。默认情况下,MapReduce将每一行分别独立地传递到if (value == null || value.toString == null) { return; } String[] line = value.toString().split("\t"); if (line == null || line.length() < 5 || line[4] == null) { return; } 方法中,因此,如果您确实想将多行作为一条消息读取,则必须编写自定义map或对数据进行预格式化,以便每个评论的所有数据都在同一行。