【发布时间】:2014-04-16 16:31:18
【问题描述】:
我正在制作一个应用程序,我将在其中获取推文并将它们存储在数据库中。我将有一列用于完整的推文文本,另一列只保留推文的单词(我需要单词来计算以后最常用的单词)。
我目前的做法是使用 6 个不同的 .replaceAll() 函数,其中一些函数可能会被触发两次。例如,我将有一个 for 循环来使用 replaceAll() 删除每个“主题标签”。
问题是我每隔几分钟就会编辑多达数千条推文,我认为我这样做的方式不会太高效。
我的要求是按这个顺序(下面也用 cmets 写的):
- 删除所有提及的用户名
- 删除所有 RT(转发标志)
- 删除所有提及的主题标签
- 用空格替换所有换行符
- 用单空格替换所有双空格
- 删除除空格以外的所有特殊字符
这是一个简短且可编译的示例:
public class StringTest {
public static void main(String args[]) {
String text = "RT @AshStewart09: Vote for Lady Gaga for \"Best Fans\""
+ " at iHeart Awards\n"
+ "\n"
+ "RT!!\n"
+ "\n"
+ "My vote for #FanArmy goes to #LittleMonsters #iHeartAwards"
+ " htt…";
String[] hashtags = {"#FanArmy", "#LittleMonsters", "#iHeartAwards"};
System.out.println("Before: " + text + "\n");
// Delete all usernames mentioned (may run multiple times)
text = text.replaceAll("@AshStewart09", "");
System.out.println("First Phase: " + text + "\n");
// Delete all RT (retweets flags)
text = text.replaceAll("RT", "");
System.out.println("Second Phase: " + text + "\n");
// Delete all hashtags mentioned
for (String hashtag : hashtags) {
text = text.replaceAll(hashtag, "");
}
System.out.println("Third Phase: " + text + "\n");
// Replace all break lines with spaces
text = text.replaceAll("\n", " ");
System.out.println("Fourth Phase: " + text + "\n");
// Replace all double spaces with single spaces
text = text.replaceAll(" +", " ");
System.out.println("Fifth Phase: " + text + "\n");
// Delete all special characters except spaces
text = text.replaceAll("[^a-zA-Z0-9 ]+", "").trim();
System.out.println("Finaly: " + text);
}
}
【问题讨论】:
-
在执行替换代码之前将字符串按空格拆分成单词会更有效吗?然后分别对每个单词运行匹配过滤器。
-
您的一些模式可以合并为一个,例如
"#FanArmy|#LittleMonsters|#iHeartAwards" -
@Salauyou 我编辑了我的代码以更好地描述主题标签在我的主应用程序中的处理方式。
-
我明白了...让我解释一个性能问题。如您所知,在 Java 中,
String对象是不可变的,因此每个与旧字符串至少相差 1 个字符的新字符串都必须是另一个对象——因此会执行分配内存和创建对象的操作。 -
但是!
replaceAll方法内部不使用字符串,它对StringBuilder对象执行操作,该对象是可变的,因此每次更改操作要便宜得多。正如我所提到的,您可以将要替换的子字符串组合成一个正则表达式模式——您可以在for循环中执行此操作,并将这种组合模式应用于您的字符串一次。
标签: java regex string performance replace