正则表达式匹配联系人组

3

我在尝试编写PHP正则表达式匹配模式,以将字符串匹配并拆分为所需的组时遇到了问题。

情况如下...我有多个包含联系人信息的字符串:

+35 00000000, info@company.com, www.company.com
这将给我:
第1组: +35 00000000, info@company.com, www.company.com

+35 00000000, +360000000, info@company.com, www.company.com
这将给我:
第1组: +35 00000000
第2组: +36 00000000, info@company.com, www.company.com

info@company.com, www.company.com
这将给我:
第1组: info@company.com, www.company.com

+35 00000000, info@company1.com, www.company1.com, +36 00000000, info@company2.com, www.company2.com
这会给我:
组1:+35 00000000,info@company1.com,www.company1.com
组2:+36 00000000,info@company2.com,www.company2.com

正如您所看到的,这些字符串可能是不同的。我需要做的是将这些字符串分成联系人组,其中:

  • 通常以电话号码(+)开头,但并非总是如此,可以只包含一个
  • 如果未提供电话,则可以以网站链接或电子邮件开始
  • 可以包含多个不同公司的组

因此,首先尝试匹配以电话号码开头并以网站结尾的组:

((\+?[\d ]+)?(, )?(.*)(, )?(www\.\w+\.\w{2,})?)

但这并不完全匹配。然后尝试简化所有内容并匹配以电话号码开头的组:
(\+[\d ]+).*

但这只匹配完整的字符串。

必须说我在正则表达式方面是个大菜鸟。我能做基本的匹配,但这对我来说太难了。

模式的长度或低性能并不重要,因为这将是一次性执行。


或许你可以通过 , 拆分字符串,然后扫描分隔的字段呢?如果可以不使用正则表达式解决问题,那么就不要使用它。 - Daniel W.
尝试使用 (?=[^\s,])(\+?\d(?:[\d\s]*\d)?)?(?:(?:,\s*|^)(\S+@\S+)\b)?(?:(?:,\s*|^)(www\.\S+)\b)?,请参见demo。或者,使用 (?=[^\s,])(\+?\d(?:[\d\s]*\d)?)?(?:(?:,\s*)?(\S+@\S+)\b)?(?:(?:,\s*)?(www\.\S+)\b)? (demo) - Wiktor Stribiżew
@DanielW. 这是我的首选,但我不知道如何在不知道它们是否在同一组中(例如,如果我有一个由6个元素组成的数组)的情况下将电话号码与网站匹配。 - meexo
@WiktorStribiżew 第二个模式看起来非常有前途。也许你应该考虑将其发布为解决方案。 - meexo
2个回答

2
您可以使用以下方法获取匹配项:
 (?:\+?\d+(?:\h+\d+)*,\h*)?[^\s@]+@[^\s@,]+,\h*www\.\S+|\+?\d+(?:\h+\d+)*

该模式匹配:
  • (?:\+?\d+(?:\h+\d+)*,\h*)? 匹配一个可选的 +,然后是带有可选空格的数字
  • [^\s@]+@[^\s@,]+ 匹配类似电子邮件的模式,只匹配单个 @
  • ,\h*www\.\S+ 匹配逗号后跟着的 www. 和 1 个或多个非空格字符
  • | 或者
  • \+?\d+\h*\d+ 匹配电话号码的模式

正则表达式演示

或者使用交替符 | 对网址和电子邮件地址进行双向匹配

(?:\+?\d+(?:\h+\d+)*,\h*)?(?:[^\s@]+@[^\s@,]+,\h*www\.\S+|\h*www\.\S+,\h*[^\s@]+@[^\s@,]+)|\+?\d+(?:\h+\d+)*

Regex demo


1
谢谢您的建议。然而,被接受的答案也解决了第一组以网站结尾且第二组只有网站的情况。 - meexo

2

您可以使用以下方法获取带有期望组的匹配结果:

(?=[^\s,])(\+?\d(?:[\d\s]*\d)?)?(?:(?:,\s*)?(\S+@\S+)\b)?(?:(?:,\s*)?(www\.\S+)\b)?

请参见正则表达式演示

注意使用(?=[^\s,])前瞻来避免匹配空字符串。

详细信息:

  • (?=[^\s,]) - 下一个字符必须是逗号和空格以外的字符
  • (\+?\d(?:[\d\s]*\d)?)? - 一个可选的第1组:一个可选的+,一个数字,然后是零个或多个数字和空格,最后是一个数字
  • (?:(?:,\s*)?(\S+@\S+)\b)? - 可选的一个出现次数为
    • (?:,\s*)? - 一个可选的逗号和零个或多个空格的出现次数
    • (\S+@\S+)\b - 第2组:一个或多个非空格字符,@,一个或多个非空格字符,一个单词边界
  • (?:(?:,\s*)?(www\.\S+)\b)? - 可选的一个出现次数为
    • (?:,\s*)? - 一个可选的逗号和零个或多个空格的出现次数
    • (www\.\S+)\b - 第3组:www.,一个或多个非空格字符,一个单词边界。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接