首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >电子邮件匹配正则表达式在java中需要很长时间,但在java脚本中计算速度很快

电子邮件匹配正则表达式在java中需要很长时间,但在java脚本中计算速度很快
EN

Stack Overflow用户
提问于 2015-01-10 05:13:09
回答 3查看 111关注 0票数 0

下面的Java电子邮件验证代码需要很长时间才能给出答案。

代码语言:javascript
复制
/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/* Name of the class has to be "Main" only if the class is public. */
class abc {
    private static Pattern validEmailPattern = Pattern.compile("^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*"
            + "@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$");

    public static void validateEmailPattern(String emailId) {
        Matcher emailMatcher = validEmailPattern.matcher(emailId);
        if (emailMatcher.matches()) {
            System.out.println("MATCHED");
        } else {
            System.out.println("UN- MATCHED");
        }

    }

    public static void main (String[] args) {
        String emailId = "tmaloneysdkjhrfsdlfhsldhflsdhflshlfhsf+NA5@amazonsdafshkjhfksefskdhkjksdhhfskjhfjhkhkffakhfkahskfhkahsdkjhf840h0ry0wy430ohwrghkcghkvlbhj.com";
        long start = System.currentTimeMillis();
        validateEmailPattern(emailId);
        long end = System.currentTimeMillis();
        System.out.println(end-start);
    }
}

而javascript中的计数器部分提供了很好的性能:

代码语言:javascript
复制
var email = "tmaloneysdkjhrfsdlfhsldhflsdhflshlfhsf+NA5@amazonsdafshkjhfksefskdhkjksdhhfskjhfjhkhkffakhfkahskfhkahsdkjhf840h0ry0wy430ohwrghkcghkvlbhj.com";

//Email is stored as a request preference whose max length is 200. Although email can be of 256 characters,
if (email.length <= 200) {
    var validEmailRegex = /^[a-zA-Z0-9!#$%&'*+\/=?\^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?\^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/;

    if(validEmailRegex.test(email)) {
        console.log("Matched");
    } else {
        console.log("Not Matched");
    }
}

这里有一个相同的小提琴:http://jsfiddle.net/amandeepautam/HKhw8/548/注意,有问题的电子邮件字符串长度不到200个字符。

造成这种情况的原因是什么?对java代码有什么建议的优化方案?我能想到的一个优化是(没有实现)将正则表达式分解成小的独立正则表达式,并评估域,独立启动中间部分。

EN

回答 3

Stack Overflow用户

发布于 2015-01-10 05:16:11

要在java中匹配电子邮件,请使用regex:

代码语言:javascript
复制
"(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"

代码语言:javascript
复制
public static boolean isEmail(String mail)
{
    return Pattern.compile("(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])").matcher(mail).find();
}

我查看了您的正则表达式,以发现灾难性的回溯:在Java正则表达式中,您没有转义第一个非捕获组开头的点和第二个非捕获组末尾的点。如果您避开了它们,正则表达式的运行速度会快得多,而不会出现灾难性的回溯。

在您的JavaScript正则表达式中,您已经正确地避开了这些点。

更正后的java正则表达式为:

代码语言:javascript
复制
"^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$"
票数 2
EN

Stack Overflow用户

发布于 2015-01-10 05:26:12

可能的问题是你的正则表达式中出现了catastrophic backtracking

要正确使用电子邮件正则表达式是相当困难的。

票数 0
EN

Stack Overflow用户

发布于 2015-01-10 06:30:24

回溯问题。

我会试一下html5规格中的这个。

http://www.w3.org/TR/html5/forms.html#valid-e-mail-address

代码语言:javascript
复制
 # "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"

 ^ 
 [a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+ 
 @
 [a-zA-Z0-9] 
 (?:
      [a-zA-Z0-9-]{0,61} 
      [a-zA-Z0-9] 
 )?
 (?:
      \. 
      [a-zA-Z0-9] 
      (?:
           [a-zA-Z0-9-]{0,61} 
           [a-zA-Z0-9] 
      )?
 )*
 $ 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27869316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档