PHP 从电子邮件正文中获取取消订阅 URL

PHP Get unsubscribe URL from email body

提问人:BenNov 提问时间:1/26/2022 更新时间:1/28/2022 访问量:134

问:

我有一封电子邮件的 HTML 正文。我只需要解析其中的取消订阅链接。 因此,如果在 dom 中的任何一点有某种链接,包含“取消订阅”一词, 我需要返回该特定链接的 URL。 我尝试了不同的正则表达式,但我似乎找不到取消订阅的 URL,或者有时根本找不到。

$regexp = "<a\s[^>]*href=(\"??)([^\" >]*?)\\1[^>]*>(.*(?:unsubscribe).*)<\/a>";
preg_match_all("/$regexp/iU", $body, $matches);
var_dump($matches);

这是行不通的:/

谢谢

PHP 正则表达 HTML 解析

评论


答:

0赞 Stefan Teunissen 1/26/2022 #1

我无法快速找到仅使用正则表达式解决您的问题的方法,所以我希望您对使用比正则表达式更多的PHP感到满意。

这是我想出的:

$regexp = '<a\s+(?:[^>]*?\s+)?href=[\'|"]([^"\']*)[\'|"]>(.*?)<\/a>';
preg_match_all("/$regexp/i", $body, $matches);

$urls = $matches[1];
$tagContents = $matches[2];

$unsubscribeUrls = [];
for ($i = 0; $i < count($tagContents); $i++) {
    if(!isset($urls[$i]) || !isset($tagContents[$i])){
        continue;
    }
    if(stripos($tagContents[$i],  "unsubscribe") !== false){
        $unsubscribeUrls[] = $urls[$i];
    }
}
var_dump($unsubscribeUrls);

这将首先匹配所有代码,并将它们拆分为 URL 和代码内容。然后,使用 PHP,它将检查标签的内容是否包含“取消订阅”。如果是这样,它将被添加到变量中。此变量应包含所需的所有 URL。a$unsubscribeUrls

1赞 The fourth bird 1/27/2022 #2

您可以使用 DOMXpath 并检查锚点是否包含不区分大小写的 unsubscribe 匹配项,并使用 getAttribute 获取 url 以获取 .href

$data = <<<DATA
This is a link <a href="https://stackoverflow.com/">SO</a> and this is <a href="http://test.test">unsubscribe</a> and 
another and this is <a href="http://test.test">UnSubScribe</a>.
DATA;

$dom = new DomDocument();
$dom->loadHTML($data);
$xpath = new DOMXPath($dom);
$query = "//a[contains(translate(., 'UNSUBSCRIBE', 'unsubscribe'),'unsubscribe')]";
$anchors = $xpath->query($query);

foreach ($anchors as $a) {
    echo sprintf("%s: %s" . PHP_EOL,
        $a->nodeValue,
        $a->getAttribute("href")
    );
}

输出

unsubscribe: http://test.test
UnSubScribe: http://test.test

查看 PHP 演示

评论

1赞 The fourth bird 2/2/2022
@BenNov尝试$dom->loadHTML($input, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);