代码之家  ›  专栏  ›  技术社区  ›  Persimmonium

根据RFC2822验证消息ID的正则表达式

  •  4
  • Persimmonium  · 技术社区  · 14 年前

    我还没有找到一个regexp来做这个。我需要验证电子邮件中的“Message ID:”值。它类似于电子邮件地址验证regexp,但要简单得多,没有电子邮件地址允许的大多数边缘情况,从 rfc2822

    msg-id          =       [CFWS] "<" id-left "@" id-right ">" [CFWS] 
    id-left         =       dot-atom-text / no-fold-quote / obs-id-left
    id-right        =       dot-atom-text / no-fold-literal / obs-id-right
    no-fold-quote   =       DQUOTE *(qtext / quoted-pair) DQUOTE
    no-fold-literal =       "[" *(dtext / quoted-pair) "]"
    

    rfc2822号

    4 回复  |  直到 14 年前
        1
  •  5
  •   Nathan    11 年前

    如果有人感兴趣的话,我们的一位高级架构师研究了RFC2822的许多层,并提出了下面的regex,其中包括左右两边的引用。规范指出,新实现不应使用过时的字符,因此此正则表达式不允许它们:

    ((([a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*)|("(([\x01-\x08\x0B\x0C\x0E-\x1F\x7F]|[\x21\x23-\x5B\x5D-\x7E])|(\\[\x01-\x09\x0B\x0C\x0E-\x7F]))*"))@(([a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*)|(\[(([\x01-\x08\x0B\x0C\x0E-\x1F\x7F]|[\x21-\x5A\x5E-\x7E])|(\\[\x01-\x09\x0B\x0C\x0E-\x7F]))*\])))
    
        2
  •  3
  •   Persimmonium    14 年前

    因为我找不到任何东西,所以我自己完成了。根据RFC2822,这不是一个正确的验证,但现在已经足够好了:

    static String VALIDMIDPATTERN = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*";
    private static Pattern patvalidmid = Pattern.compile(VALIDMIDPATTERN);
    
    public static boolean isMessageIdValid(String midt) {
        String mid = midt;
        if (StringUtils.countMatches(mid, "<") > 1)
            return false;
        if (StringUtils.countMatches(mid, ">") > 1)
            return false;
        if (StringUtils.containsAny(mid, "<>")) {
            mid = StringUtils.substringBetween(mid, "<", ">");
            if (StringUtils.isBlank(mid)) {
                return false;
            }
        }
        if (StringUtils.contains(mid, "..")) {
            return false;
        }
        //extract from <>
        mid = mid.trim();
        //now validate
        Matcher m = patvalidmid.matcher(mid);
        return m.matches();
    }
    
        3
  •  1
  •   KingPong    12 年前

    使用标准正则表达式不可能完全匹配RFC2822消息ID,因为CFWS规则允许嵌套注释,而regex无法处理这些注释。例如

    <foo@bar.com> (comment (another comment))
    
        4
  •  -3
  •   cordellcp3    14 年前