2016-06-26 13 views
0

文字列に含まれる複数の相対リンクがあります。しかし、私はあまりにも単純なjavascript:alert("Sorry You Cannot Do That.")とすべてのリンクを置き換えてほしいと私はhttp://google.com/conf/bin.htmlのような相対的な経路だけを変更するような絶対的な経路を欲しくない。ここでphp regexローカルの相対パスを置き換えます

は例のコードスニペットです:

$pattern = "/<a(.*) href='\/(.*)'(.*)>reply</a>/"; 
$string = "<a target='_blank' href='/conf/bin?post=5760627b29ba0' name='bin' id='bin' class='bin' title='Hide From Feed'></a> 
wow 
<a target='_blank' href='/conf/bin?post=5760627b29ba0' name='bin' id='bin' class='bin' title='Hide From Feed'></a> wow"; 
while (preg_match($pattern, $string)){ 

$string = preg_replace($pattern, "<tr><td align='right'><a href='javascript:alert(" . chr(34) . "Sorry You Cannot Do That" . chr(34) . ")' style='text-decoration:none;'>reply</a>", $string); 
} 

そして私は、文字列のように終わるしたい:

$string = "<a target='_blank' href='javascript:alert(" . chr(34) . "Sorry You Cannot Do That" . chr(34) . ")' name='bin' id='bin' class='bin' title='Hide From Feed'></a> 
wow 
<a target='_blank' href='javascript:alert(" . chr(34) . "Sorry You Cannot Do That" . chr(34) . ")' name='bin' id='bin' class='bin' title='Hide From Feed'></a> wow"; 

誰でも助けることができます。 ありがとうございます

+0

私はこれにパーサを使用したいと思います。 – chris85

+0

@ chris85あなたは私にどのように表示できますか? – Achmed

+0

ドメインへの絶対URLの予想される動作は何ですか? – chris85

答えて

1

domdocumentを使用してHTMLを解析し、正規表現を使用してURLを検証できます。

$string = "<a target='_blank' href='/conf/bin?post=5760627b29ba0' name='bin' id='bin' class='bin' title='Hide From Feed'></a> 
wow 
<a target='_blank' href='/conf/bin?post=5760627b29ba0' name='bin' id='bin' class='bin' title='Hide From Feed'></a> wow 
<a target='_blank' href='http://www.google.com/conf/bin?post=5760627b29ba0' name='bin' id='bin' class='bin' title='Hide From Feed'></a>"; 
$string .= '<script type="text/javascript">function send_alert(){ alert("Sorry You Cannot Do That.");}</script>'; 
$doc = new DOMDocument(); 
$doc->loadHTML($string); 
foreach($doc->getElementsByTagName('a') as $link) { 
    if(preg_match('~^(?!https?://)~', $link->getAttribute('href'))) { 
     $link->setAttribute('href', 'javascript:send_alert();'); 
    } 
} 
echo $doc->saveHTML(); 

PHPデモ:https://eval.in/595820
正規表現のデモ:https://regex101.com/r/mP2gC8/1

または代替引用されたバージョン:

$string = "<a target='_blank' href='/conf/bin?post=5760627b29ba0' name='bin' id='bin' class='bin' title='Hide From Feed'></a> 
wow 
<a target='_blank' href='/conf/bin?post=5760627b29ba0' name='bin' id='bin' class='bin' title='Hide From Feed'></a> wow 
<a target='_blank' href='http://www.google.com/conf/bin?post=5760627b29ba0' name='bin' id='bin' class='bin' title='Hide From Feed'></a>"; 
$doc = new DOMDocument(); 
$doc->loadHTML($string); 
foreach($doc->getElementsByTagName('a') as $link) { 
    if(preg_match('~^(?!https?://)~', $link->getAttribute('href'))) { 
     $link->setAttribute('href', 'javascript:alert(decodeURIComponent(\'Sorry You Cannot Do That.\'));'); 
    } 
} 
echo $doc->saveHTML(); 

デモ:https://eval.in/595836

0

あなたはすべての「」のタグを見つけることができます。このライブラリーではhttp://simplehtmldom.sourceforge.net/ :あなたはすべてを見つけるとき

$html = new simple_html_dom(); 
$html->load_file($string); 

$link = $html->find('a'); 

を「」要素その後、あなたは チェック「どのようにHTML要素を変更するには、」タブ例えば

それのいくつかの部品を交換することができます
$link = $html->find('a')->href = 'new value of href' 
1

あなたはDOMDocumentオブジェクトは、XPathと組み合わせて使用​​することができ、かつXPathクエリでそのようなタグをすべて取得する:

0あなたの質問のように
//a[starts-with(@href, '/') and text()='reply'] 

a - タグのために、このテスト:

  • は「絶対」パス(例えばないhref値を持っていますhttp://google.comではなく、abc/def/ghi.phpまたは/abc/x.php)、および
  • は、タグコンテンツとしてreplyを持っています。

最初のテストでは、コロン(:)の不在をテストできます。

hrefの値をjavascriptに置き換えた場合、新しいブラウザウィンドウを不必要に開くので、targetプロパティも削除する必要があります。ここで

はコードです:

$doc = new DOMDocument(); 
$doc->loadHTML($string); 
$xpath = new DOMXpath($doc); 
foreach($xpath->query("//a[not(contains(@href, ':')) and text()='reply']") as $link) { 
    $link->setAttribute('href', 'javascript:alert("Sorry You Cannot Do That");'); 
    // remove any target attribute 
    $link->removeAttribute('target'); 
} 
// remove the stuff that DOMDocument has added: 
echo preg_replace("/^.*\<BODY>(.*)<\/BODY><\/HTML>$/is", "$1", $doc->saveHTML()); 

それはあなたがandornot()、、...などとXPathクエリを構築する方法eval.in

注上で実行を参照してください。

+0

すべての相対/ローカルパスを変更することが可能です – Achmed

+0

このxpathを使用してプロトコル(「http://」など)がないことを確認できます: '// a [not(contains(@href、 ': '))とtext()=' reply '] 'です。私はそれを私の答えに加えました。あなたは 'と'、 'や'、 'not()'、などで必要に応じてより複雑な式を作ることができます。 – trincot

+0

これはあなたの質問に答えましたか? – trincot

関連する問題