循环数据提取所有以 .co.uk 结尾的电子邮件地址


loop over data extract all email addresses that ends with .co.uk

我试图通过以下挑战来提高我的编程(PHP(技能。接下来的问题与其说是关于代码问题,不如说是关于代码,而是关于应该应用的编程逻辑。

    (9,'zxvvgf@housecapades.com',0,0,1,1,0,1,1),
    (10,'qwer@rogers.co.uk',1,0,0,1,0,0,1),
    (11,'lorenIpsum@hotmail.com',0,0,0,1,0,0,1),
    (12,'BarackObama@googlemail.co.uk',1,0,9,1,1,1,1),
    (13,'DonaldTrump@courtesysupportteam.net',0,0,9,1,1,1,1),
    (15,'Mcaine@mynet.com',1,0,9,1,1,1,1),
    (16,'davestra_@hotmail.com',0,0,0,1,0,0,1),
    (17,'lewisHamilton@carracing.co.uk',1,0,9,1,1,1,1)

目的

考虑上面的以下数据转储,我需要找到一种方法来仅提取以.co.uk结尾的电子邮件地址并将其输入数据库表中。 在此示例中,只有 2 个以 .co.uk 结尾的电子邮件地址,即 BarackObama@googlemail.co.uklewisHamilton@carracing.co.uk

普莱姆

我很难弄清楚如何解决这个问题,因为:

  1. 没有(大多数(电子邮件地址的字符数不同
  2. 电子邮件地址之间有不相关的数据,更具体地说是数字,应该忽略

我的逻辑/伪代码

  1. 在行中查找一个公分母(我注意到第一列是整数,每行增加一(使用它为变量$min$max赋值(在此示例中$min=9$max=17(

  2. 使用上面分配的变量遍历行,每次迭代都会增加循环 1

  3. 内部循环 忽略所有属于集成器的字符

  4. 使用 pregmatch 查找以 .co.uk 结尾的电子邮件地址

  5. 如果找到,则添加到数组$couk_emails否则循环到下一行

  6. 当循环结束时将数组$couk_emails上传到数据库表

这就是我想出的逻辑/伪装,但对我来说感觉有缺陷。我认为这是一个相当困难的挑战,所以我很想听听有经验的程序员将如何解决这类问题。

请注意,本文中的所有电子邮件地址都是虚构的/据我所知编造

尝试为此目的使用正则表达式
像这样的东西——

'(.*?'.co'.uk)'

正则表达式解释在这里.

您可以使用 function.
将 php 中的字符串与正则表达式匹配preg_match用一个简单的例子来测试这一点 -

>>> $regex = "/'(.*?'.co'.uk)'/"
>>> $str = "(12,'BarackObama@googlemail.co.uk',1,0,9,1,1,1,1),"
>>> preg_match($regex, $str, $match)
=> 1
>>> $match
=> [
       "'BarackObama@googlemail.co.uk'",
       "BarackObama@googlemail.co.uk"
   ]

解释
在上面的代码中,preg_match 接收要匹配的$regex$str,并根据它是否匹配字符串返回01.

要提取字符串的电子邮件部分并丢弃其余部分(如正则表达式中使用的单引号(,您需要将相应的部分放在一个capturing group中,该将在第三个参数(上面示例中的$match变量(的匹配数组中返回>><<。最后,$match[0]包含与正则表达式匹配的整个字符串,$match[1]仅包含电子邮件。

算法中的前三个步骤是无用的。

我假设您已经将数据拆分为行。如果不是,则可以使用explode()将文本拆分为行。

算法:

  1. 创建一个空列表(array(来保存结果;
  2. 使用 foreach 循环输入列表;
  3. 使用 preg_match() 检测当前行中的电子邮件地址是否以 .co.uk 结尾; preg_match() 还提取变量中的电子邮件地址;
  4. 如果与步骤 3 匹配,则将提取的电子邮件地址放入输出列表(在步骤 1 中创建(;
  5. 就这样。对电子邮件列表做任何你需要的事情;将它们放入数据库,显示它们,忽略它们,没关系。您在此步骤中执行的任何处理都不是此算法的一部分;它要么是一种新算法,要么与这个算法一起,它只是一个更大处理的步骤。

代码:

$text = "(9,'zxvvgf@housecapades.com',0,0,1,1,0,1,1),
(10,'qwer@rogers.co.uk',1,0,0,1,0,0,1),
(11,'lorenIpsum@hotmail.com',0,0,0,1,0,0,1),
(12,'BarackObama@googlemail.co.uk',1,0,9,1,1,1,1),
(13,'DonaldTrump@courtesysupportteam.net',0,0,9,1,1,1,1),
(15,'Mcaine@mynet.com',1,0,9,1,1,1,1),
(16,'davestra_@hotmail.com',0,0,0,1,0,0,1),
(17,'lewisHamilton@carracing.co.uk',1,0,9,1,1,1,1)";

$input  = explode("'n", $text);    // 0. prepare the input data
$output = array();                 // 1. prepare the output
foreach ($input as $line) {        // 2. loop over the input
    $match = array();
    if (preg_match("/'([^']*''.co''.uk)'/", $line, $match)) {   // 3. check if matches
        $output[] = $match[1];     // 4. put the extracted email address aside
    }
}
print_r($output);                  // 5. print the results for visual validation

输出:

Array
(
    [0] => qwer@rogers.co.uk
    [1] => BarackObama@googlemail.co.uk
    [2] => lewisHamilton@carracing.co.uk
)

惊喜!有三个以 .co.uk 结尾的电子邮件地址。


更新

这个问题清楚地表明,它不是关于代码,而是关于代码背后的逻辑。以下是没有回答该问题的附录;它显示了 PHP 函数的功能。

受OP关于输入数据不一定是一组行而是大文本的评论的启发,我建议使用以下代码,它比上面的代码运行得更快,但它不会提高任何人的逻辑技能:

$match = array();
preg_match_all("/'([^']*''.co''.uk)'/", $text, $match);
print_r($match[1]);

它使用相同的正则表达式,这次使用 preg_match_all() . preg_match_all()提取$matches[0]中匹配的片段(用撇号包围的电子邮件(和与$matches[1]括号中的表达式匹配的片段。这是预期的输出。

此而已:

select * from emailtable e where e.email LIKE '%co.uk';

或将地址反向保存在 2 秒内。比 mysql 可以使用索引

update emailtable set e.remail = reverse(e.email);
select * from emailtable e where e.remail LIKE 'ku.oc%';