简单的正则表达式冻结应用程序

时间:2013-11-16 15:27:52

标签: java android regex

我想检查文字是否包含电话号码或域名。以前,我删除所有空格。如果没有命中应用程序冻结。为什么呢?

String aboutText = about.getText().toString();
String aboutTextClear = aboutText.replaceAll("\\s+", "");
Matcher phone = Patterns.PHONE.matcher(aboutTextClear);
Matcher domain = Patterns.DOMAIN_NAME.matcher(aboutTextClear);
if(phone.find() || domain.find()) {
    return;
}

https://github.com/android/platform_frameworks_base/blob/master/core/java/android/util/Patterns.java

1 个答案:

答案 0 :(得分:0)

对于较大的字符串值,DOMAIN实际上可能需要很长时间才能匹配。在匹配之前删除空格会使事情变得更糟,因为现在潜在的域名可能会更大......无空间文本的长序列会对TLD部分的负点击产生大量的回溯。 / p>

我会考虑使用更简单的表达式将输入拆分为“已知”较小的块,然后匹配较小的部分。这将减少反向跟踪正则表达式中的问题范围。

因此,由于电话号码正则表达式更简单,IPAddress更简单,我会分三个阶段进行,并保留最后一个域名(如果可以,最好从表达式中删除IP地址部分)。 ..)

这当然假设输入文本很大,但是做了类似的事情:

Matcher phone = Patterns.PHONE.matcher(aboutText); // no space manipulation...
if (phone.find()) {
    return;
}
for (String word : aboutText.split("\\s+")) {
    Matcher ipaddress = Patterns.IP_ADDRESS.matcher(aboutText); // no space manipulation...
    if (ipaddress.find()) {
        return;
    }

    Matcher domain = Patterns.DOMAIN_NAME.matcher(aboutTextClear);
    if(domain.find()) {
        return;
    }
}