我尝试删除所有标点(“,;:!?()[]”)以及所有使用hadoopapache中java的wordcount代码的html实体(&…)(https://hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapreducetutorial.html). 如果我只删除带有分隔符的标点符号,它的效果就和从stringescapeutils包中删除带有unescapehtml(word)的html实体一样好。
但是当我同时运行它们时,html实体仍然存在,我看不出我的代码有什么问题。
public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable>{
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString(),".,;:!?()[]\t\n\r",true);
while (itr.hasMoreTokens()) {
String next_word = itr.nextToken();
if(next_word.contains("&")){
next_word = StringEscapeUtils.unescapeHtml(next_word);
}
word.set(next_word);
context.write(word, one);
}
}
}
有人能解释一下有什么问题吗?
1条答案
按热度按时间dluptydi1#
这是一个使用正则表达式从输入文件的文本中过滤出html实体和标点符号的经典例子。
为了做到这一点,我们需要创建两个正则表达式,分别用来匹配html实体和标点符号,并将它们从文本中删除,最后将剩余的有效单词设置为键值对。
从html实体开始,比如
,<
,和>
,我们可以发现这些标记总是以&
字符并以;
中间有许多字母字符的字符。因此,基于regex语法(您可以自己学习,如果您还没有学习,那么它非常有价值),下面的表达式匹配所有这些标记:(我们也可以在这里使用在线regex测试仪进行测试):
接下来,对于标点符号,我们可以简单地通过简单地查找既不是字母也不是数字(当然也不是空格)的字符来匹配它们,例如下一个正则表达式:
(在删除与上一个正则表达式匹配的html实体后,再次使用在线regex测试仪进行测试):
所以为了使用这些正则表达式,我们可以简单地使用
replaceAll()
方法,该方法基于第一个参数的regex将与之匹配的所有标记更改为第二个参数字符串的值。在这里,我们可以将所有匹配的标记更改为一个简单的空格,并继续在最后删除所有的双空格,以便只保留有效的单词作为键放入Map器的键值对中。所以程序现在看起来是这样的:
并使用以下文本文件内容作为输入:
这是给定的输出: