2016-06-17 2 views
3

Der Versuch, den Wert des folgenden Elements zu analysieren:PHP preg_match nicht wie in anderen Web-Anwendungen arbeiten

input type = "hidden" name = "csrf_token" value = "VUNht8fnmxmJXJIMassWW8SAwWKNJ3SC8POA4FtSqEKhG1rcoB3ZNqcPqa615tPsF_hzW0l4zDjSEHJYMz9Ogw ==">

Gebiet rund um das Element sieht wie folgt aus:

  <input type="hidden" name="redirect" value=""> 
      <input type="hidden" name="invite_code" value=""> 
      <input type="hidden" name="invite" value=""> 
      <input type="hidden" name="country" value=""> 
      <input type="hidden" name="csrf_token" value="325fTt31vp42rbt90gNqBT923_Z04snI5tmhCOAhSzpmL2mr3NBAho1zp6bEirZrLdQna5Ocm6_iC3OYdbBqLg=="> 

      <div> 

Mit folgendem Code l ine:

preg_match("/csrf_token. value=.(.+==).>/", $result, $output_array); 

$ output_array leer gelassen wird, wo, wie in http://www.phpliveregex.com/ die Regex korrekt ist.

Was mache ich falsch?

+1

' "../Csrf_token Wert = (.? + ==)>/s"' –

+0

@ WiktorStribiżew scheint nicht zu arbeiten, auch das/s gibt an, dass der Punkt mit einer neuen Zeile übereinstimmt, und das möchte ich nicht. – Keddy1201

+1

Funktioniert hier, https://eval.in/590926. Vielleicht ist Ihr '$ result' nicht das, was Sie erwartet haben. Auch mit einem Parser können Sie einfach den Wert des Attributs" value "ziehen. – chris85

Antwort

1

Die Regex Way

Ersetzen Sie den wörtlichen Raum mit \s+:

preg_match("/csrf_token.\s+value=.(.+==).>/", $result, $output_array); 

Auch Sie wahrscheinlich noch ein paar anderen Dingen verbessern mögen. Einige Vorschläge:

  • Statt . die " entsprechen, verwenden ['\"]? (weniger allgemein, vermeidet auf etwas zufällig wie csrf_token2 passend).
  • Anstelle .+==, verwenden Sie [^='"]+=* (das gleiche Ergebnis, aber viel bessere Leistung und Übereinstimmungen Tokens, die in 1 oder Null enden = s).

Mit diesen Anregungen, würde Ihr Code sein:

preg_match("/csrf_token['\"]?\s+value=['\"]?([^='\"]+=*)['\"]?>/", $result, $output_array); 

hier ein working demo.

Der bessere Weg

Sie analysieren nicht HTML mit regex, überhaupt nicht. Verwenden Sie einfach einen Parser.

+0

Scheint auch nicht zu funktionieren, werde mit dem gehen, was @ chris85 über die Verwendung eines Parsers gesagt hat. – Keddy1201

2

Hier ist eine Parser-Version:

<?php 
$doc = new DOMDocument(); 
$doc->loadHTML('<input type="hidden" name="csrf_token" value="VUNht8fnmxmJXJIMassWW8SAwWKNJ3SC8POA4FtSqEKhG1rcoB3ZNqcPqa615tPsF_hzW0l4zDjSEHJYMz9Ogw==">'); 
foreach ($doc->getElementsByTagName('input') as $input) { 
    if ($input->getAttribute('name') == 'csrf_token') { 
     echo $input->getAttribute('value'); 
    } 
} 

Demo: https://eval.in/590936

5

Gerade meine zwei Cent zu setzen, einen Weg mit einer XPath-Abfrage mit DOMDocument:

<?php 

$html = <<<EOF 
      <input type="hidden" name="redirect" value=""> 
      <input type="hidden" name="invite_code" value=""> 
      <input type="hidden" name="invite" value=""> 
      <input type="hidden" name="country" value=""> 
      <input type="hidden" name="csrf_token" value="325fTt31vp42rbt90gNqBT923_Z04snI5tmhCOAhSzpmL2mr3NBAho1zp6bEirZrLdQna5Ocm6_iC3OYdbBqLg=="> 
      <div> 
EOF; 

$dom = new DOMDocument(); 
$dom->loadHTML($html); 

$xpath = new DOMXPath($dom); 

$inputs = $xpath->query("//input[@name='csrf_token']/@value"); 
foreach ($inputs as $input) { 
    echo $input->nodeValue; 
    # 325fTt31vp42rbt90gNqBT923_Z04snI5tmhCOAhSzpmL2mr3NBAho1zp6bEirZrLdQna5Ocm6_iC3OYdbBqLg== 
} 

// alternatively, if you're sure there's ALWAYS only ONE element, pick the first one 
echo $xpath->query('//input[@name="csrf_token"]/@value')->item(0)->nodeValue; 
?> 

a demo on ideone.com See.

2

einen DOM-Parser Verwenden Sie die Werte alle mit '//input[@name="csrf_token"]' XPath müssen holen (und zwar alle input Tags erhalten, die ein name Attribut mit dem csrf_token Wert enthalten).

Siehe ein example:

$html = <<<DATA 
<div> 
<input type="hidden" name="redirect" value=""> 
<input type="hidden" name="invite_code" value=""> 
<input type="hidden" name="invite" value=""> 
<input type="hidden" name="country" value=""> 
<input type="hidden" name="csrf_token" value="325fTt31vp42rbt90gNqBT923_Z04snI5tmhCOAhSzpmL2mr3NBAho1zp6bEirZrLdQna5Ocm6_iC3OYdbBqLg=="> 
</div> 
DATA; 

$dom = new DOMDocument('1.0', 'UTF-8'); 
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); 

$xpath = new DOMXPath($dom); 
$inputs = $xpath->query('//input[@name="csrf_token"]'); 
$res = array(); 
foreach($inputs as $input) { 
    array_push($res, $input->getAttribute("value")); 
} 
print_r($res); 

Ausgang:

Array 
(
    [0] => 325fTt31vp42rbt90gNqBT923_Z04snI5tmhCOAhSzpmL2mr3NBAho1zp6bEirZrLdQna5Ocm6_iC3OYdbBqLg== 
) 
+0

Sie könnten direkt darauf zugreifen: 'echo $ xpath-> query ('// input [@ name =" csrf_token "]/@ value') -> item (0) -> nodeValue;' wenn es immer nur eine gibt ** Element. – Jan

+0

Was ist, wenn es mehr gibt? Ich habe gerade einen Weg gezeigt, all diese Werte zu bekommen. Natürlich kennen wir das HTML nicht, und die Anforderungen sind nicht klar. –

+0

Sie kennen die Antwort, dann ist das Schleifen des Ergebnisses, wie Sie bereits tun, der Weg zu gehen :) – Jan