【问题标题】:loop over data extract all email addresses that ends with .co.uk循环数据提取所有以 .co.uk 结尾的电子邮件地址
【发布时间】:2015-11-19 01:41:05
【问题描述】:

我正在尝试通过应对以下挑战来提高我的编程 (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和@ 987654328@)

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

  3. 内部循环忽略所有整数类型的字符

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

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

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

这就是我想出的逻辑/Psuedo,但我觉得它有缺陷。我认为这是一个相当艰巨的挑战,所以我很想听听经验丰富的程序员如何解决这类问题

请注意,这篇文章中的所有电子邮件地址都是虚构的/据我所知是虚构的

【问题讨论】:

  • 如果您可以循环遍历,一次一行,对于单行,如9,'zxvvgf@housecapades.com',0,0,1,1,0,1,1,您可以执行以下操作之一:1) 使用strpos/stripos 确定是否有任何.co.uk 在里面。 2)在,的基础上拆分内容,在$split[1]上做一些preg_match

标签: php mysql


【解决方案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's comment 的启发,关于输入数据不一定是一组行而是一个大文本,我建议以下代码运行速度比上面的代码快得多,但它不会提高任何人的逻辑技能:

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

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

【讨论】:

  • 谢谢先生,您清楚地知道您的东西,在我接受您的回答之前,如果您不介意,我还有一个问题....在您的代码中,您使用了 $input = explode("\n", $text); //to prepare the input data. 让我们假设所有文本不在新行上。我是否正确地说我可以执行以下操作:$input = explode("),", $text); 准备输入数据,因为每一行都以 ), 结尾
  • 确实,如果所有数据都在同一行上,您必须找到不同的分隔符将其拆分为行。没错,), 也可以用作分隔符。
【解决方案2】:

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

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

正则表达式explanation here.

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

>>> $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] 仅包含电子邮件。

【讨论】:

    【解决方案3】:

    就是这样:

    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%';
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-28
      • 1970-01-01
      • 2017-11-08
      • 2015-12-07
      • 2012-10-03
      • 1970-01-01
      • 2016-04-12
      • 1970-01-01
      相关资源
      最近更新 更多