使用正则表达式从多个行中分离数据

时间:2018-10-11 11:08:53

标签: php regex

我有以下数据行:

City:  London
Email:  main@email.com

Name:    Mr.Test
Emails:  email1@mail.com
      email2@mail.com
invalid-email-too

使用以下代码:

if(preg_match('/\nEmails: (.*).\n/s', $query, $matches)) {
    return $matches[1];
}

我得到这样的字符串结果:

email1@mail.com
          email2@mail.com

但是我需要它作为已经分开的结果作为数组。 然后,最好的解决方案也是使用“ Email:”和“ Emails:”来获得数组结果。 请问如何使用一个正则表达式呢?

2 个答案:

答案 0 :(得分:1)

您可以使用

'~(?:\G(?!\A)|^Emails:)\s*\K\S+@\S+\.\S+~m'

请参见regex demo

详细信息

  • (?:\G(?!\A)|^Emails:)-Emails:在行首(^Emails:,请注意,m修饰符使^匹配字符串的开头和全部行开始位置)或上一个匹配项的结尾(\G(?!\A)
  • \s*-超过0个空格
  • \K-匹配重置运算符将匹配的所有文本从整个匹配缓冲区中丢弃掉
  • \S+@\S+\.\S+-类似于电子邮件的模式:1+个非空格,@,1+个非空格,.,以及1+个非空格。

PHP usage

if (preg_match_all('~(?:\G(?!\A)|^Emails:)\s*\K\S+@\S+\.\S+~m', $s, $matches)) {
    print_r($matches[0]); // => Array ( [0] => email1@mail.com [1] => email2@mail.com ) 
}

答案 1 :(得分:0)

这是一种简单的方法,但是似乎效果很好,至少对于您的示例数据而言。它只是在电子邮件地址出现在任何位置之后

#output
    Path to optimum:
- Features:   60  Init   :                       Perf = 0.26936  Diff: NA  *
- Features:   59  Remove : V59                   Perf = 0.2403  Diff: 0.029055  *
- Features:   58  Remove : V10                   Perf = 0.22588  Diff: 0.014424  *
- Features:   57  Remove : V20                   Perf = 0.20669  Diff: 0.019186  *

Stopped, because no improving feature was found.

Demo

这种方法会出错的地方是,如果您的文本中出现的电子邮件地址以$input = "City: London\nEmail: main@email.com\n\nName: Mr.Test\nEmails: email1@mail.com\n email2@mail.com"; preg_match_all ("/\b\w+@[^.]+\.\w+\b/U", $input, $array); print_r($array[0]); Array ( [0] => main@email.com [1] => email1@mail.com [2] => email2@mail.com ) 开头,并且不是 。在这种情况下,此答案将给出错误的匹配。