2017-02-03 8 views
4

のは、私はこのようになり、データベース内のHTMLを持っているとしましょう:PHPの正規表現の否定

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> 

今、私は2番目と3番目のURLをつかむが、最初のを無視するPHPの正規表現を使用します。

私がこれまで持っている正規表現式は次のとおりです。

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

それはかなりうまく動作しますが、私はそれが/除外するURLの最初のタイプで始まり、1を否定作る方法がわからない:HREF !=」

助けてください、ありがとう

+1

それらのそれぞれを検索し、(最終的に)新しいリンクノードを作成し、その後、(リンクを避けて)最初のDOMDocument/DOMXPathを使うことの最大のテキストノードを抽出します。 –

+0

preg_matchを使ってPHPですべてをやりたいのですが、HTMLがデータベースにあり、コードがすでに構造化されているからです。 – liquidgraph

+1

正規表現を使用してHTMLを解析しないでください。 http://php.net/DomDocument – miken32

答えて

1

"negative lookbehind"の正規表現機能を使用して、後の作業を行うことができます。私はあなたの正規表現の最初の部分を修正するために((?<!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 
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_-]+に置き換えることができます。https?:\/\/[a-zA-Z.]*のようなより正確なパターンで[a-zA-Z\/\/:\.]*の部分を置き換えることもできます。