我不是正则表达式的初学者,但它们在perl中的使用似乎与Java有点不同。
无论如何,我基本上都有一个速记词及其定义的字典。我想迭代字典中的单词并用它们的含义替换它们。在JAVA中这样做的最佳方式是什么?
我见过String.replaceAll(),String.replace()以及Pattern / Matcher类。我希望按照以下方式进行不区分大小写的替换:
word =~ s/\s?\Q$short_word\E\s?/ \Q$short_def\E /sig
虽然我在这里,你认为最好从字符串中提取所有单词,然后应用我的字典或只是将字典应用到字符串?我知道我需要小心,因为简写的单词可以与其他简写含义相匹配。
希望这一切都有道理。
感谢。
澄清:
字典就像: lol:大声笑出声,rofl:在地板上滚动着笑,ll:喜欢柠檬
字符串是: 大声笑,我是rofl
替换文字: 大声笑,我在地板上笑着滚动
注意ll没有添加到任何地方
答案 0 :(得分:2)
危险是正常词语中的误报。 “跌倒”!=“felikes lemons”
一种方法是在空格上拆分单词(需要保存多个空格吗?)然后在List上执行上面的'if contains(){replace} else {output original}想法。
我的输出类是StringBuffer
StringBuffer outputBuffer = new StringBuffer();
for(String s: split(inputText)) {
outputBuffer.append( dictionary.contains(s) ? dictionary.get(s) : s);
}
让你的分割方法足够聪明,还可以返回单词分隔符:
split("now is the time") -> now,<space>,is,<space>,the,<space><space>,time
然后你不必担心保留空格 - 上面的循环只会将不是字典单词的任何内容附加到StringBuffer。
这是retaining delimiters when regexing上最近的SO帖子。
答案 1 :(得分:2)
如果您坚持使用正则表达式,这将起作用(采用Zoltan Balazs的字典映射方法):
Map<String, String> substitutions = loadDictionaryFromSomewhere();
int lengthOfShortestKeyInMap = 3; //Calculate
int lengthOfLongestKeyInMap = 3; //Calculate
StringBuffer output = new StringBuffer(input.length());
Pattern pattern = Pattern.compile("\\b(\\w{" + lengthOfShortestKeyInMap + "," + lengthOfLongestKeyInMap + "})\\b");
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
String candidate = matcher.group(1);
String substitute = substitutions.get(candidate);
if (substitute == null)
substitute = candidate; // no match, use original
matcher.appendReplacement(output, Matcher.quoteReplacement(substitute));
}
matcher.appendTail(output);
// output now contains the text with substituted words
如果您计划处理多个输入,预先编译模式比使用String.split()
更有效,Pattern
每次调用都会编译一个新的Pattern pattern = Pattern.compile("\\b(lol|rtfm|rofl|wtf)\\b");
// rest of the method unchanged, don't need the shortest/longest key stuff
。
(编辑)将所有键编译成单个模式会产生更有效的方法,如下所示:
{{1}}
这允许正则表达式引擎跳过任何恰好足够短但不在列表中的单词,从而为您节省大量的地图访问权。
答案 2 :(得分:1)
首先,我想到的是:
...
// eg: lol -> laugh out loud
Map<String, String> dictionatry;
ArrayList<String> originalText;
ArrayList<String> replacedText;
for(String string : originalText) {
if(dictionary.contains(string)) {
replacedText.add(dictionary.get(string));
} else {
replacedText.add(string);
}
...
或者您可以使用StringBuffer而不是replacedText
。