2014-06-09 7 views
1

Je suis en train d'extraire d'une chaîne (source tout site web alla chercher par CURL -)PHP regex - matchs vides

<tr> 
    <td><a href="http://www.gpw.pl/karta_spolki/LT0000128555/">AAL</a></td> 
<td><a href="http://www.gpw.pl/karta_spolki/LT0000128555/">AVIAAM LEASING AB</a></td> 
</tr> 
<tr class="even"> 
    <td><a href="http://www.gpw.pl/karta_spolki/PLTRNSU00013/">AAT</a></td> 
    <td><a href="http://www.gpw.pl/karta_spolki/PLTRNSU00013/">ALTA SPÓŁKA AKCYJNA</a></td> 

Je voudrais obtenir toutes les ancres 3 caractères doivent correspondre dans un tableau pour exemple AAL et AAT (il y a plus)

Ce que j'est:

$subject = curl_exec($ch);   
$pattern = '`<td><a href="http://www\.gpw\.pl/karta_spolki/[0-9A-Za-z ]+/">[0-9A-Z]{3}</a></td>`'; 
preg_match_all($pattern, $subject, $matches, PREG_PATTERN_ORDER); 
print_r($matches); 

en conséquence je reçois

Array ([0] => Array ()) 

Pourriez-vous me donner des conseils pour le résoudre?

+2

Avez-vous envisagé d'utiliser l'outil DOM (DOMDocument) ou similaire? –

+0

je ne ai pas - je pensais que ce serait plus pratique de cette façon (regex) – andrewpo

+1

Regex n'est pas génial pour le HTML. Il y a une réponse plutôt drôle [ici] (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/) – user184994

Répondre

1

Vous pouvez utiliser un objet DOMDocument pour construire votre tableau comme ceci:

$doc = new DOMDocument(); 
$doc->LoadHTML($str); 

$matches = array(); 
foreach($doc->getElementsByTagName('a') as $a) { 
    $text = $a->nodeValue; 
    if(strlen($text) === 3) $matches[] = $text; 
} 

Cela itérer tous les éléments d'ancrage dans votre chaîne HTML et construire ce tableau:

Array 
(
    [0] => AAL 
    [1] => AAT 
) 
+0

'DOMDocument' est utile si l'on peut effectivement ** récupérer ** le contenu via un appel' curl'. Vérifie ma réponseLe contenu de base sur la page que l'affiche originale tente d'extraire est en cours de chargement via AJAX. Donc la structure DOM est juste un cadre vide avant l'AJAX. Ce qui signifie que l'expression régulière échouera et que le document DOM échouera. – JakeGould

+0

@JakeGould assez juste, je ne suis pas allé aussi loin que de visiter les pages qui ont été liées à comme le contenu apparent a été fourni dans la question. Il semble que vous ayez repéré la cause du problème, mais existe-t-il une solution? –

+0

Donc, je pensais que c'était AJAX au début. Mais je crois que j'ai trouvé l'URL réelle utilisée. Et la regex échoue en effet. J'ai donc créé mon propre appel curl et j'ai refait la regex pour travailler avec le contenu HTML actuel. Fonctionne maintenant! – JakeGould

1

I juste essayé votre exemple & votre regex fonctionne comme prévu avec le petit échantillon fourni:

$subject = <<<EOT 
<tr> 
    <td><a href="http://www.gpw.pl/karta_spolki/LT0000128555/">AAL</a></td> 
<td><a href="http://www.gpw.pl/karta_spolki/LT0000128555/">AVIAAM LEASING AB</a></td> 
</tr> 
<tr class="even"> 
    <td><a href="http://www.gpw.pl/karta_spolki/PLTRNSU00013/">AAT</a></td> 
    <td><a href="http://www.gpw.pl/karta_spolki/PLTRNSU00013/">ALTA SPÓŁKA AKCYJNA</a></td> 
EOT; 

$pattern = '`<td><a href="http://www\.gpw\.pl/karta_spolki/[0-9A-Za-z ]+/">[0-9A-Z]{3}</a></td>`'; 
preg_match_all($pattern, $subject, $matches, PREG_PATTERN_ORDER); 

echo '<pre>'; 
print_r($matches); 
echo '</pre>'; 

Les résultats:

Array 
(
    [0] => Array 
     (
      [0] => AAL 
      [1] => AAT 
     ) 

) 

Mais cela dit, je fait déterrer ce que je crois est your source URL pour la demande curl, et il échoue quand je le tester. Donc, je me suis ajusté le regex à ceci:

/(?<=>)[0-9A-Z]{3}(?=<\/a><\/td>)/is 

Et maintenant, les choses semblent bien travailler ensemble avec mon code qui tente de recréer la demande curl que vous faites.

// Set the URL. 
$url="http://www.gpw.pl/lista_spolek_en"; 

// The actual curl request. 
$curl_timeout = 5; 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $curl_timeout); 
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13'); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
$subject = curl_exec($ch); 
curl_close($ch); 

// Set the regex pattern. 
$pattern = '/(?<=>)[0-9A-Z]{3}(?=<\/a><\/td>)/is'; 

// Run the preg match all command with the regex pattern. 
preg_match_all($pattern, $subject, $matches, PREG_PATTERN_ORDER); 

// Return the results. 
echo '<pre>'; 
print_r($matches); 
echo '</pre>'; 

Et la sortie qui semble bien fonctionner de mon point de vue:

Array 
(
    [0] => Array 
     (
      [0] => AAL 
      [1] => AAT 
      [2] => ABC 
      [3] => ABE 
      [4] => ABM 
      [5] => ABS 
      [6] => ACE 
      [7] => ACG 
      [8] => ACP 
      [9] => ACS 
      [10] => ACT 
      [11] => ADS 
      [12] => AGO 
      [13] => AGT 
      [14] => ALC 
      [15] => ALM 
      [16] => ALR 
      [17] => ALT 
      [18] => AMB 
      [19] => AMC 
      [20] => APL 
      [21] => APN 
      [22] => APT 
      [23] => ARC 
      [24] => ARR 
      [25] => ASB 
      [26] => ASE 
      [27] => ASG 
      [28] => AST 
      [29] => ATC 
      [30] => ATD 
      [31] => ATG 
      [32] => ATL 
      [33] => ATM 
      [34] => ATP 
      [35] => ATR 
      [36] => ATS 
      [37] => AWB 
      [38] => AWG 
      [39] => EAT 
      [40] => ACP 
      [41] => ALR 
      [42] => BZW 
      [43] => EUR 
      [44] => JSW 
      [45] => KER 
      [46] => KGH 
      [47] => LPP 
      [48] => LTS 
      [49] => LWB 
      [50] => MBK 
      [51] => OPL 
      [52] => PEO 
      [53] => PGE 
      [54] => PGN 
      [55] => PKN 
      [56] => PKO 
      [57] => PZU 
      [58] => SNS 
      [59] => TPE 
     ) 

) 
+0

Bien joué pour le faire fonctionner mais je ne pense toujours pas que l'utilisation d'une expression régulière est la voie à suivre ici. Si vous voulez que toutes les balises d'ancrage dont le contenu est de trois caractères, vous pouvez aussi le demander directement. –