繁体   English   中英

如何使用正则表达式替换字符串的一部分

[英]how to replace parts of string using regular expressions

我不是正则表达式的初学者,但是它们在perl中的使用似乎与Java中有所不同。

无论如何,我基本上都有速记词典及其定义。 我想遍历字典中的单词,并用其含义替换它们。 在JAVA中执行此操作的最佳方法是什么?

我见过String.replaceAll(),String.replace()以及Pattern / Matcher类。 我希望按照以下方式进行不区分大小写的替换:

word =~ s/\\s?\\Q$short_word\\E\\s?/ \\Q$short_def\\E /sig

当我在使用它时,您是否认为最好从字符串中提取所有单词,然后应用我的字典,或者仅将字典应用于字符串? 我知道我需要小心,因为速记词可能会与其他速记词义相匹配。

希望这一切都有道理。

谢谢。

澄清:

字典就像:大声笑:大声笑,rofl:在地板上笑,ll:像柠檬

字符串是:大声笑,我是rofl

替换文字:大声笑出来,我在地板上笑

请注意ll没有在任何地方添加

危险是正常单词内的误报。 “跌倒”!=“喜欢柠檬”

一种方法是在空白处分割单词(是否需要保留多个空格?),然后遍历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方法足够聪明以返回单词定界符:

split("now is the  time") -> now,<space>,is,<space>,the,<space><space>,time

然后,您不必担心节省空白-上面的循环只会将不是字典单词的任何内容附加到StringBuffer。

这是最近在进行正则表达式时保留定界符的 SO线程。

如果您坚持使用正则表达式,则可以使用(采用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

这允许正则表达式引擎跳过恰好足够短但不在列表中的任何单词,从而为您节省了大量的地图访问权限。

我想到的第一件事是:

...
// 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM