我刚刚用Java创建了一个正则表达式,我想在大约5000条推文中寻找表达式,每条推文花费大约一秒钟,为什么它如此慢?
如果表达太复杂或者表面上有什么东西要执行它太贵了?我希望在不到5秒的时间内处理整个数据。
代码是:
public class RegularExpression {
public static void main(String[] args) throws IOException {
String filter = ".*\"created_at\":\"(.*?)\".*\"content\":\"(.*?word.*?)\",\"id\".*";
Pattern pattern = Pattern.compile(filter);
List<String> tweets = FileUtils.readLines(new File("/tmp/tweets"));
System.out.println("Start with " + tweets.size() );
int i=0;
for (String t : tweets){
Matcher matcher = pattern.matcher(t);
matcher.find();
System.out.println(i++);
}
System.out.println("End");
}
}
输入是JSON推文。如果我做我的RE更简单它运行得更快,但是,我认为我的RE不是那么重。我想知道为什么会发生这种情况,我只是在检查测试。
更新:
当我尝试解析JSON时,我之所以使用RE,是因为最终,我可以从任何类型的服务器获得简单的文本,XML,JSON格式,日志。所以,我必须像普通文本一样使用我的输入。
答案 0 :(得分:2)
你的正则表达式在允许匹配方面非常不精确。最重要的是,您似乎想要在引号之间匹配文本,但是您允许引号字符成为匹配的一部分(.*
可以并且将很乐意匹配"
!)。根据您的输入,这会为正则表达式引擎在声明失败/成功之前必须检查的可能非常多的排列设置进行设置。
如果实际上引号可能不是您目前与.*
匹配的文字的一部分,请改用[^"]*
;这应该加快它的速度:
"[^\"]*\"created_at\":\"([^\"]*)\"[^\"]*\"content\":\"([^\"]*word[^\"]*)\",\"id\"[^\"]*"
答案 1 :(得分:2)
由于您已经知道输入是JSON,因此不应使用正则表达式来解释它。使用JSON解析器,然后您不必关心转义特殊字符等任何事情。
答案 2 :(得分:1)
我不完全确定为什么处理一条推文需要几乎一秒钟的时间,但是懒惰的量词比“匹配直到”-scenario的“匹配任何东西”更昂贵。
此处提供更多信息:http://blog.stevenlevithan.com/archives/greedy-lazy-performance
您可以尝试避免使用延迟量词,或者只使用JSON解析器,因为它可能更快/更清晰。