区分电子邮件地址和 IRI

Distinguish between email address and IRI

我有一个可以包含电子邮件地址或 IRI(国际化 URI)的字符串。这些字符串不包含额外的周围空格或任何 HTTP linefolding 字符。此外,它们不包含在相应规范中标记为“过时”的任何元素。我需要一种简单的方法来区分字符串包含哪些内容。

我正在查看我认为是最新的相应规范:RFC 5322 § 3.4.1. Addr-Spec Specification for emails, and RFC 3987 § 2.2. ABNF for IRI References and IRIs IRI。我想出了以下算法,括号中有解释:

  1. 如果字符串以引号 " 字符开头,则为电子邮件地址。 (电子邮件地址 local-part 可能是带引号的字符串,但 IRI scheme 可能不是。)
  2. 否则找到第一个 @ 符号或冒号 : 字符。
    • 如果遇到的字符是 @ 符号,则该字符串包含电子邮件地址。
    • 否则,如果它是一个冒号 : 字符,则该字符串包含一个 IRI。

这种方法正确吗?还有另一种更简单的方法吗?最后,作为奖励,我将如何扩展该算法以将这两者与 IP 地址(包括 IPv4 和 IPv6)区分开来?

我认为指定的规则是正确的并且可以快速确定类型(电子邮件或 IRI)。要将其扩展到 IP 地址,应添加相应的语法:https://datatracker.ietf.org/doc/html/draft-main-ipaddr-text-rep-00.

那么您的规则可以扩展为:

规则:(我假设输入格式正确)

  • 第一个字符 " => 电子邮件
  • 第一个字符 : => IpV6(因为 IRI 该方案必须包含至少一个字符)
  • :@ 中的第一个
    • @ => 电子邮件

    • : =>

      • 如果不符合IpV6的语法=> IRI

      • 否则:有歧义,也在语法上,有些选项

        1. 用作 IpV6 => 它将有效,可能是预期的东西

        2. 用作 IRI => 第一部分(':' 之前)将是一个方案,后面的部分将是一个 'segment' 协议

          • 所以ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff会导致方案ffff和'segment'ffff:ffff:ffff:ffff:ffff:ffff:ffff

          • 我觉得这种情况不太可能发生

        3. 引发异常,这可能是一个有效选项,具体取决于环境

    • 两者都不在字符串中=> IpV4

ipchar := hex / ':'
hex    := [0-9A-Fa-f]