2

正規表現を使用した mailto 属性を持つアンカーから電子メール アドレスを取得する必要があります。

このパターン:(.*)<a\s(.*?)(.*)\s*href\=['"]mailto:([-a-z0-9_]+)@([a-z0-9-]+).([a-z]+)['"]>(.*)</a>(.*)

PHP では動作しませんが、regex コーチで動作します。

コード:

preg_match("'(.*)<a (.*?)(.*) *href\=['\"]mailto:([-a-z0-9_]+)@([a-z0-9-]+).([a-z]+)['\"]>(.*)</a>(.*)'si", "<a href=\"mailto:someemail@ohio.com\"">Some email</a>", $matches);

print_r($matches);

では、なぜそれがphpで機能するのでしょうか?

4

3 に答える 3

5

PHP の PCRE では、パターンとオプションの修飾子を区切るデリミタに正規表現をラップする必要があります。この場合、英数字以外の最初の文字 (つまり) が使用されるため、パターンは実際には正しく、残りは修飾子として扱われます。が適切にエスケープされておらず、残りも有効な修飾子ではないため、これは無効な正規表現です。'(.*)<a (.*?)(.*) *href\=[[

他の人がすでに示唆しているように、正規表現内の区切り文字の出現をエスケープするか'、正規表現に表示されない別の区切り文字を選択することでこれを修正できます。

しかしそれ以外にも、正規表現で HTML を解析しようとすると、非常にエラーが発生しやすくなります。あなたの場合、それを多く使用すると.*、パフォーマンスが低下します(正規表現の処理方法が原因です)。

PHP の DOM ライブラリのようにクエリできる DOM を返す適切な HTML パーサーを使用することをお勧めします。

$doc = new DomDocument();
$doc->loadHTML($str);
foreach ($doc->getElementsByTagName("a") as $a) {
    if ($a->hasAttribute("href")) {
        $href = trim($a->getAttribute("href"));
        if (strtolower(substr($href, 0, 7)) === 'mailto:') {
            $components = parse_url($href);
        }
    }
}
于 2010-11-23T16:55:45.647 に答える
1

あなたの区切り文字は quote'であり、正規表現にはいくつかのインスタンスがあります:

preg_match("'(.*)<a (.*?)(.*) *href\=['\"]mailto:([-a-z0-9_]+)@([a-z0-9-]+).([a-z]+)['\"]>(.*)</a>(.*)'si", "<a href=\"mailto:someemail@ohio.com\"">Some email</a>", $matches);
                                      ^                                              ^

それらをエスケープする (例: \') か、区切り文字を変更します。

于 2010-11-23T16:43:01.980 に答える
0
if (preg_match('#<a\s.*?href=[\'"]mailto:([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6})[\'"].*?>.*?</a>#i', $subject, $regs)) {
    $result = $regs[0];
} else {
    $result = "";
}
于 2010-11-23T16:43:27.490 に答える