Youtube URL的PHP​​ Regex否定

时间:2017-02-03 22:21:21

标签: php regex regex-negation

假设我在数据库中有HTML,如下所示:

Hello world!

<a href="https://www.youtube.com/watch?v=m7t75u72vd">ABC</a>

Blah blah blah...

https://www.youtube.com/watch?v=df82vnx07s

Blah blah blah...
<p>https://www.youtube.com/watch?v=nvs70fh17f3fg</p>

现在我想使用PHP正则表达式获取第二个和第三个URL,但忽略第一个。

我到目前为止的正则表达式是:

\s*[a-zA-Z\/\/:\.]*youtu(be.com\/watch\?v=|.be\/)([a-zA-Z0-9\-_]+)

它运作良好,但我不知道如何排除/否定第一种类型的URL,一种以:href =“

开头

请帮助,谢谢!

3 个答案:

答案 0 :(得分:1)

你可以使用&#34;负面的背后&#34;正则表达式功能可以完成您之后的工作。我已经通过添加((?<!href=[\'"])http)来修改你的正则表达式的开头来实现一个。希望它有所帮助!

$regex    = '/((?<!href=[\'"])http)[a-zA-Z\/\/:\.]*youtu(be.com\/watch\?v=|.be\/)([a-zA-Z0-9\-_]+)/';
$useCases = [
    1 => '<a href="https://www.youtube.com/watch?v=m7t75u72vd">ABC</a>',
    2 => "<a href='https://www.youtube.com/watch?v=m7t75u72vd'>ABC</a>",
    3 => 'https://www.youtube.com/watch?v=df82vnx07s',
    4 => '<p>https://www.youtube.com/watch?v=nvs70fh17f3fg</p>'
];
foreach ($useCases as $index => $useCase) {
    $matches = [];
    preg_match($regex, $useCase, $matches);
    if ($matches) {
        echo 'The regex was matched in usecase #' . $index . PHP_EOL;
    }
}
// Echoes:
// The regex was matched in usecase #3
// The regex was matched in usecase #4

答案 1 :(得分:0)

如果匹配后跟(?![^<]*>)以外的0 +字符跟随<,则您需要添加一个>否定前瞻,这将导致匹配失败:

[a-zA-Z\/:.]*youtu(?:be\.com\/watch\?v=|\.be\/)([a-zA-Z0-9\-_]+)(?![^<]*>)
                                                                   ^^^^^^^^^^

请参阅regex demo

注意我还转义了.符号以匹配文字点,并使用了非be部分的捕获组。如果您对捕获不感兴趣,可以将([a-zA-Z0-9\-_]+)替换为[a-zA-Z0-9_-]+,也可以使用更精确的模式替换[a-zA-Z\/\/:\.]*部分,例如https?:\/\/[a-zA-Z.]*

答案 2 :(得分:0)

示例解决方案:

(?![^<]*>)[a-zA-Z\/\/:\.]*youtu(be.com\/watch\?v=|.be\/)([a-zA-Z0-9\-_]+)

Visualization with an explanation