2016-06-26 7 views
0

Ich habe mehrere relative Links, die in einer Zeichenfolge enthalten sind. Ich möchte aber auch alle Links durch eine einfache javascript:alert("Sorry You Cannot Do That.") ersetzen und ich möchte keine absoluten Pfade wie http://google.com nur die relativen Pfade wie /conf/bin.html ändern. HierPHP Regex ersetzen lokale relative Pfade

ist ein Beispiel-Code-Snippet:

$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); 
} 

Und ich möchte, dass die Zeichenfolge, um am Ende als:

$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"; 

kann jemand helfen. Danke

+0

Ich würde einen Parser dafür verwenden. – chris85

+0

@ chris85 kannst du mir zeigen wie? – Achmed

+0

Was ist das erwartete Verhalten einer absoluten URL zu Ihrer Domain? Lassen Sie sie so wie sie ist? – chris85

Antwort

1

Sie können domdocument verwenden, um den HTML-Code und dann einen Regex zu analysieren, um den URL zu validieren.

$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 Demo: https://eval.in/595820
Regex Demo: https://regex101.com/r/mP2gC8/1

oder eine Alternative zitierte Version:

$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(); 

Demo: https://eval.in/595836

0

Sie können z.B. http://simplehtmldom.sourceforge.net/ Mit dieser Bibliothek können Sie alle ‚ein‘ Tag finden:

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

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

Wenn Sie alle ‚a‘ Elemente finden, dann können Sie einen Teil davon prüfen ersetzen Tab zB

„Wie HTML-Elemente ändern“
$link = $html->find('a')->href = 'new value of href' 
1

Sie können DOMDocument mit XPath kombiniert verwenden und Holen Sie alle solche Tags mit einer XPath-Abfrage:

//a[starts-with(@href, '/') and text()='reply'] 

Wie in Frage dieses Tests für a -Tags, dass:

  • einen href Wert haben, der nicht ein "absoluter" Pfad (z nicht http://google.com, sondern abc/def/ghi.php oder /abc/x.php), und
  • haben als tag-content reply.

Für den ersten Test konnten Sie nur für das Fehlen des Doppelpunkts testen (:).

Beachten Sie, dass wenn Sie den Wert href durch JavaScript ersetzen, sollten Sie auch die target Eigenschaft entfernen, da dies unnötigerweise ein neues Browserfenster öffnen würde.Hier

ist der Code:

$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()); 

anzeigen laufen auf eval.in

Hinweis, wie Sie XPath-Abfragen mit and zu bauen, or, not(), , ... etc.

+0

Ist es möglich, alle relativen/lokalen Pfade zu ändern – Achmed

+0

Sie könnten mit diesem xpath nach dem Fehlen des Protokolls suchen (wie 'http: //'): '// a [not (enthält (@href, ': ')) und text() =' antworten '] '. Ich fügte das meiner Antwort hinzu. Sie können komplexere Ausdrücke nach Bedarf mit 'and',' oder', 'not()', ... etc erstellen. – trincot

+0

Hat dies Ihre Frage beantwortet? – trincot