【问题标题】:Java regex string output not as expectedJava 正则表达式字符串输出不符合预期
【发布时间】:2014-04-04 07:09:00
【问题描述】:

我正在尝试根据给我的特定准则编写一些代码来验证电子邮件地址,其中一个准则是诸如 cath@[10.1.1] 之类的地址应该是有效的。我被卡住了,无法弄清楚我的正则表达式字符串有什么问题:

 "[A-Za-z0-9._%+-]+[@|_at_]+[\\[|[A-Za-z0-9-]]+[0-9\\.|_dot_]+[\\]|com|com.au|co.ca|co.nz|co.us|co.uk]{2,4}"

这是一些示例输出:

Enter an email address
cath@[10.1.1]
cath@[10.1.1] is not a valid email address
cath@[10.1.1.a]
cath@[10.1.1.a] is a valid email address
cath@[10.1.1.]
cath@[10.1.1.] is a valid email address

最后两个输入/输出应该是无效的,而第一个应该是有效的。谁能指出我正确的方向?谢谢

编辑 - 这是我的代码,如果它可以帮助任何人

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

public class EmailAddresses {

  public static void main(String[] args) {

    String line;        
    System.out.println("Enter an email address");
    Scanner scan = new Scanner(System.in);
    while (scan.hasNextLine()) {

      line = scan.nextLine();
      Pattern pattern = Pattern.compile("[A-Za-z0-9._%+-]+(?:@|_at_)(?:\\[|[A-Za-z0-9-])(?:0-9\\.|_dot_)(?:\\]|com|com\\.au|co\\.ca|co\\.nz|co\\.us|co\\.uk){2,4}");
      Matcher mat = pattern.matcher(line);

      if(mat.matches()){
        line = line.toLowerCase();
        System.out.println(line + " is a valid email address");
      }else{
        System.out.println(line + " is not a valid email address");
      }
    }
  }
}

【问题讨论】:

  • 你绝对需要使用 one 正则表达式吗?分开工作会更容易
  • 不,我不必,我只是不知道我可以把它分开吗?
  • 好吧,例如,开始尝试找到分隔符(@_at_),对其进行拆分,分别验证两个部分等

标签: java regex validation email


【解决方案1】:

以下是正则表达式风格对初始正则表达式的理解:

我认为有一个误解。括号[] 创建一个字符类:characters 替代序列。

这里的括号用于声明一系列单词的替代品,这不是有意的行为。要声明替代词的序列,请使用非捕获组(?:...),在该组内,使用逻辑运算符|

例如:

"[\\[|[A-Za-z0-9-]]+" 变为 "(?:\\[|[A-Za-z0-9-])+"

试试这个正则表达式:

^[A-Za-z0-9._%+-]+(?:@|_at_)(?:\[(?:\d|\.|_dot_)+(?<!\.)\]|[A-Za-z\d._-]+\.(?:com|com\.au|co\.ca|co\.nz|co\.us|co\.uk))$

说明

演示

http://regex101.com/r/dS8qF4

【讨论】:

  • 最后一组的点也应该转义
  • @fge 感谢您的评论,我已经更新了我的答案。
  • @Alex,在哪里生成这样的图表?
  • 嗨,谢谢。问号有什么作用? - 没关系你已经更新了你的答案。我试过这个正则表达式字符串,上面的示例输入都不是有效的
  • 感谢图表和解释,消除了很多困惑。早上再试一次
【解决方案2】:

由于您不限于使用单个正则表达式,我建议您拆分检查。

例如,这是一个尝试在您的输入中找到分隔符的方法:

private static int trySeparator(final String input, final String separator)
{
    int ret = input.indexOf(separator);
    if (ret == -1)
        return ret;
    return ret == input.lastIndexOf(separator) ? ret : -1;
}

@_at_ 的主要验证方法中使用它,然后将第一部分和第二部分分开并分别检查。比单个正则表达式更容易,更可测试;)

【讨论】:

  • 如何区分邮箱名称中的_at_ 和分隔邮箱名称和域名的at?即bob_at_home_at_gmail.com
  • 我建议使用_at_,而不是at。另请注意,如果多次找到分隔符,则上述方法返回 -1。
  • 感谢您的帮助,将在我不那么累的早上实施:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
相关资源
最近更新 更多