为什么这个regexp回溯不起作用



我尝试使用以下类型的regex

([_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,4}))|(FakeEmail:)|(Email:)|(12)|(13)

(假设\1是电子邮件正则表达式组,\2是FakeEmail:,\3是电子邮件:因为我没有计算出真正的分组)

我想做的是说"找到电子邮件这个词:如果你找到了,就选择这个词后面的任何电子邮件地址。"

那个电子邮件正则表达式,我得到了一些关于堆栈溢出的其他问题。

我的测试字符串可能类似

    "This guy is spamming me from
FakeEmail: fakeemailAdress@someplace.com
 but here is is real info:
Email: testemail@someplace.com"

有什么建议吗?感谢

我要么很困惑你想做什么,要么你的Regex大错特错。特别是:

为什么在结尾处使用Email:,而不是开头,以匹配您的示例?

为什么Email:12都用管道字符分隔,几乎就像它们在字段中一样?这是将模式编译为OR。(找到电子邮件模式,或者单词"电子邮件:",或者12最终的含义,因为它在这里断章取义。)

如果你想做的只是匹配Email: testemail@someplace.com之类的东西,那么你不需要任何回溯。

像这样的东西可能就是你所需要的:

Email:s+([_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,4}))

此外,我强烈建议不要试图如此严格地验证电子邮件地址。你可能想阅读http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx。我会将模式简化为更多的内容:

Email:s+(S+)*@(S+.S+)

尝试:

(Fake)?Email: *([_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,4}))

如果是真的电子邮件,则捕获的组1将为空,如果是假电子邮件,则包含"Fake",而2将是电子邮件本身。

如果它是FakeEmail,你真的想捕捉它吗?如果您想捕获所有Email,但忽略所有FakeEmail,则执行:

bEmail: *([_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,4}))

单词边界防止Email位与"FakeEmail"匹配。

UPDATE:注意您的regex只匹配小写,因为它在[]中到处都有a-z,但没有[A-Z]。确保使用忽略大小写开关将regex输入到java匹配函数中。即:

Pattern.compile("(Fake)?Email: .....", Pattern.CASE_INSENSITIVE)

您可以使用以下代码来匹配所有类型的电子邮件地址:

String text = "This guy is spamming me fromn" +
    "FakeEmail: fakeemail+Adress@someplace.comn" +
    "fakeEmail: n" +
    "fakeemail@someplace.com" +
    "but here is is real info:n" +
    "Email: test.email+info@someplace.comn";
Matcher m = Pattern.compile("(?i)(?s)Email:\s*([_a-z\d\+-]+(\.[_a-z\d\+-]+)*@[a-z\d-]+(\.[a-z\d-]+)*(\.[a-z]{2,4}))").matcher(text);
while(m.find())
    System.out.printf("Email is [%s]%n", m.group(1));

这将匹配电子邮件文本:

  • 使用(?s)在不同线路上显示
  • 使用(?i)忽略事例比较
  • 带有句点.的电子邮件地址
  • 带有加号+的电子邮件地址

输出:来自上面的代码是

Email is [fakeemail+Adress@someplace.com]
Email is [fakeemail@someplace.comb]
Email is [test.email+info@someplace.com]

最新更新