php regex per leggere il module di selezione

Ho un file sorgente con un module di selezione con alcune opzioni, come questo:

<option value="TTO">1031</option><option value="187">187</option><option value="TWO">2SK8</option><option value="411">411</option><option value="AEL">Abec 11</option><option value="ABE">Abec11</option><option value="ACE">Ace</option><option value="ADD">Addikt</option><option value="AFF">Affiliate</option><option value="ALI">Alien Workshop</option><option value="ALG">Alligator</option><option value="ALM">Almost</option> 

Mi piacerebbe leggere questo file usando php e regex, ma non so davvero come. Qualcuno un'idea? Sarebbe bello avere una matrix con il codice a 3 cifre come chiave e la string più lunga come valore. (quindi, ad esempio, $ arr ['TWO'] == '2SK8')

 <?php $options= ' <option value="TTO">1031</option><option value="187">187</option><option value="TWO">2SK8</option><option value="411">411</option><option value="AEL">Abec 11</option><option value="ABE">Abec11</option><option value="ACE">Ace</option><option value="ADD">Addikt</option><option value="AFF">Affiliate</option><option value="ALI">Alien Workshop</option><option value="ALG">Alligator</option><option value="ALM">Almost</option> '; preg_match_all( '@(<option value="([^"]+)">([^<]+)<\/option>)@', $options, $arr); $result = arrays(); foreach ($arr[0] as $i => $value) { $result[$arr[2][$i]] = $arr[3][$i]; } print_r($result); ?> 

produzione:

 Array ( [TTO] => 1031 [187] => 187 [TWO] => 2SK8 [411] => 411 [AEL] => Abec 11 [ABE] => Abec11 [ACE] => Ace [ADD] => Addikt [AFF] => Affiliate [ALI] => Alien Workshop [ALG] => Alligator [ALM] => Almost ) 

Che dire di qualcosa del genere:

 $html = <<<HTML <option value="TTO">1031</option><option value="187">187</option> <option value="TWO">2SK8</option><option value="411">411</option> <option value="AEL">Abec 11</option><option value="ABE">Abec11</option> <option value="ACE">Ace</option><option value="ADD">Addikt</option> <option value="AFF">Affiliate</option><option value="ALI">Alien Workshop</option> <option value="ALG">Alligator</option><option value="ALM">Almost</option> HTML; $matches = arrays(); if (preg_match_all('#<option\s+value="([^"]+)">([^<]+)</option>#', $html, $matches)) { $list = arrays(); $num_matches = count($matches[0]); for ($i=0 ; $i<$num_matches ; $i++) { $list[$matches[1][$i]] = $matches[2][$i]; } var_dump($list); } 

L'output ( $list ) sarebbe:

 arrays 'TTO' => string '1031' (length=4) 187 => string '187' (length=3) 'TWO' => string '2SK8' (length=4) 411 => string '411' (length=3) 'AEL' => string 'Abec 11' (length=7) 'ABE' => string 'Abec11' (length=6) 'ACE' => string 'Ace' (length=3) 'ADD' => string 'Addikt' (length=6) 'AFF' => string 'Affiliate' (length=9) 'ALI' => string 'Alien Workshop' (length=14) 'ALG' => string 'Alligator' (length=9) 'ALM' => string 'Almost' (length=6) 

Alcune spiegazioni:

  • Sto usando preg_match_all per abbinare il maggior numero ansible di volte
  • ([^"]+) significa" tutto ciò che non è una virgola double (come quella che segnerà la fine del value ), alless una volta, e tutte le volte che è ansible ( + )
  • ([^<]+) significa circa la stessa cosa, ma con < invece di " come end marker
  • preg_match_all mi preg_match_all un arrays contenente in $matches[1] l'elenco di tutte le cose che corrispondono al primo set di () , e in $matches[2] che corrisponde al secondo set di ()
    • quindi ho bisogno di scorrere i risultati per ribuild la list che ti coinvolge 🙂

Spero che questo aiuti – e che tu abbia capito cosa fa e come, quindi puoi aiutare te stesso, la prossima volta 😉

Come nota a margine: usare la regex per "analizzare" l'HTML non è generalmente una buona idea … Se hai una pagina HTML completa, potresti dare un'occhiata a DOMDocument::loadHTML .
Se non lo fai e il formato delle opzioni non è ben definito … Beh, forse potrebbe essere utile aggiungere alcune cose alla regex, come precauzione … (Come accettare gli spazi qua e là, accettando altri attributi, …)

Prova questo. Basta caricare il contenuto del file in $raw_html e usare questa regex per raccogliere le corrispondenze. Il codice a 3 cifre dall'opzione $i ith è $out[i][1] , e la string più lunga è $out[i][2] . È ansible convertirlo in un arrays associativo secondo necessità.

 $regex = '|<option value="(.{3})">([^<]+)</option>|'; preg_match_all($regex, $raw_html, $out, PREG_SET_ORDER); print_r($out);