我试图通过以下挑战来提高我的编程(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.uk
和 lewisHamilton@carracing.co.uk
普莱姆
我很难弄清楚如何解决这个问题,因为:
- 没有(大多数(电子邮件地址的字符数不同
- 电子邮件地址之间有不相关的数据,更具体地说是数字,应该忽略
我的逻辑/伪代码
在行中查找一个公分母(我注意到第一列是整数,每行增加一(使用它为变量
$min
和$max
赋值(在此示例中$min=9
和$max=17
(使用上面分配的变量遍历行,每次迭代都会增加循环 1
内部循环 忽略所有属于集成器的字符
使用 pregmatch 查找以 .co.uk 结尾的电子邮件地址
如果找到,则添加到数组
$couk_emails
否则循环到下一行当循环结束时将数组
$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
,并根据它是否匹配字符串返回0
或1
.
要提取字符串的电子邮件部分并丢弃其余部分(如正则表达式中使用的单引号(,您需要将相应的部分放在一个capturing group
中,该将在第三个参数(上面示例中的$match
变量(的匹配数组中返回>><<。最后,$match[0]
包含与正则表达式匹配的整个字符串,$match[1]
仅包含电子邮件。
算法中的前三个步骤是无用的。
我假设您已经将数据拆分为行。如果不是,则可以使用explode()
将文本拆分为行。
算法:
- 创建一个空列表(
array
(来保存结果; - 使用
foreach
循环输入列表; - 使用
preg_match()
检测当前行中的电子邮件地址是否以.co.uk
结尾;preg_match()
还提取变量中的电子邮件地址; - 如果与步骤 3 匹配,则将提取的电子邮件地址放入输出列表(在步骤 1 中创建(;
- 就这样。对电子邮件列表做任何你需要的事情;将它们放入数据库,显示它们,忽略它们,没关系。您在此步骤中执行的任何处理都不是此算法的一部分;它要么是一种新算法,要么与这个算法一起,它只是一个更大处理的步骤。
代码:
$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%';