2010-07-18 9 views
9

Esempio:Come restituire solo i gruppi con nome con preg_match o preg_match_all?

$string = "This is some text written on 2010-07-18."; 
preg_match('|(?<date>\d\d\d\d-\d\d-\d\d)|i', $string, $arr_result); 
print_r($arr_result); 

Returns:

Array 
(
    [0] => 2010-07-18 
    [date] => 2010-07-18 
    [1] => 2010-07-18 
) 

Ma io voglio che sia:

Array 
(
    [date] => 2010-07-18 
) 

Nel oggetto PDO di PHP v'è un'opzione che sta filtrando i risultati dal database rimuovendo questi valori numerati duplicati: PDO::FETCH_ASSOC. Ma non ho ancora visto un modificatore simile per le funzioni PCRE in PHP.

risposta

3

Non penso che tu possa fare preg_* farlo, ma puoi farlo con un semplice ciclo. Ma non vedo perché questi elementi rappresentano un problema.

+0

In array di piccole dimensioni questo non rappresenta un problema, ma in molto grande con molti motivi potrebbero esserci problemi con esigenze di memoria elevate. In secondo luogo, sembra più pulito in questo modo e ci sarebbe (con questo modificatore inesistente) una riga di codice in meno, quindi meno possibilità di un errore. – rsk82

+0

Al contrario: perché questo non può essere fatto da PCRE, dovresti aggiungere altro codice, dove potrebbero esserci più problemi. – Charles

+0

Intendevo gli elementi aggiuntivi nell'array. – Maerlyn

-1

Prova questo:

$string = "This is some text written on 2010-07-18."; 
preg_match('|(?<date>\d\d\d\d-\d\d-\d\d)|i',$string,$arr_result); 
echo $arr_result['date']; 
+0

no, è sbagliato, intendevo un modificatore per eliminare automaticamente le chiavi che sono numeri, non è così facile su array multiranchiati che preg_match_all potrebbe produrre – rsk82

9

preg_match non ha alcuna bandiera o opzione che lo confronta solo i rendimenti denominati (ancora). Quindi quello che vuoi non è direttamente possibile. Tuttavia è possibile rimuovere tutti gli elementi con i non-montaggio chiavi dal vostro array partite e poi si ottiene quello che stai cercando:

$matches = array_intersect_key($matches, array_flip(array('name', 'likes'))); 

Demo

3

E 'anche possibile disinserire tutti gli indici numerici prima di ritorno:

foreach (range(0, floor(count($arr_result)/2)) as $index) { 
    unset($arr_result[$index]); 
} 
1

simile a the answer che hakre postato sopra, io uso questo frammento per ottenere solo i parametri denominati:

$subject = "This is some text written on 2010-07-18."; 
$pattern = '|(?<date>\d\d\d\d-\d\d-\d\d)|i'; 
preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER); 
echo '<pre>Before Diff: ', print_r($matches, 1), '</pre>'; 
$matches = array_diff_key($matches[0], range(0, count($matches[0]))); 
echo '<pre>After Diff: ', print_r($matches, 1), '</pre>'; 

... che produce questo:

Before Array 
(
    [0] => Array 
     (
      [0] => 2010-07-18 
      [date] => 2010-07-18 
      [1] => 2010-07-18 
     ) 

) 
After Array 
(
    [date] => 2010-07-18 
) 
+0

Questo è quello che ha funzionato per me. Grazie –

8

Come restituire solo i gruppi denominati con preg_match o preg_match_all?

Attualmente non è possibile (PHP7). Si otterrà sempre una matrice di tipo misto, contenente tasti numerici e denominati.

Consente citare manuale PHP (http://php.net/manual/en/regexp.reference.subpatterns.php):

Questa subpattern verrà indicizzato nell'array partite dalla sua posizione normale numerica e anche per nome.


Per risolvere il problema i seguenti frammenti di codice possono aiutare:

1. Filtro matrice utilizzando un controllo is_string sull'array chiave (per PHP5.6 +)

$array_filtered = array_filter($array, "is_string", ARRAY_FILTER_USE_KEY); 

2.foreach sugli elementi e disinserire se chiave dell'array is_int() (tutte le versioni di PHP)

/** 
* @param array $array 
* @return array 
*/ 
function dropNumericKeys(array $array) 
{ 
    foreach ($array as $key => $value) { 
     if (is_int($key)) { 
      unset($array[$key]); 
     } 
    } 
    return $array; 
} 

La sua una semplice funzione PHP chiamata dropNumericKeys(). Si tratta della post-elaborazione di un array di corrispondenze dopo l'esecuzione di preg_match*() utilizzando gruppi con nome per la corrispondenza. Le funzioni accettano $array. Itera l'array e rimuove/rimuove tutte le chiavi con tipo intero, lasciando intatte le chiavi con tipo di stringa. Infine, la funzione restituisce l'array con "ora" solo le chiavi con nome.

Nota: la funzione è compatibile con PHP verso il basso. Funziona su tutte le versioni. La soluzione array_filter si basa sulla costante ARRAY_FILTER_USE_KEY, che è disponibile solo su PHP5.6 +. Vedere http://php.net/manual/de/array.constants.php#constant.array-filter-use-key

+0

perché definire una funzione se si dispone di una soluzione semplice come # 1 – Meisner

+2

La funzione è compatibile con PHP verso il basso. Funziona su tutte le versioni. La soluzione 'array_filter' si basa sulla costante' ARRAY_FILTER_USE_KEY', che è disponibile solo su PHP5.6 +. Vedi http://php.net/manual/de/array.constants.php#constant.array-filter-use-key –

0

ho letto nel tuo post che questi sono possibili sovraccarichi di futura memoria ecc ... In questo caso, il motivo per cui no't può essere risolto con un unset():

$string = "This is some text written on 2010-07-18."; 
preg_match('|(?<date>\d{4}-\d{2}-\d{2})|i', $string, $arr_result); 
$date = array("date" => $arr_result['date']); 
unset($arr_result, $string);//delete array and string preg_match origen 

print_r($date); 
//or create a new: 
// $arr_result = $date; 
//print_r($arr_result); 
0

io uso alcuni dei codici introdotti e questo è il codice finale funziona su PHP 5.6+:

$re = '/\d+\r\n(?<start>[\d\0:]+),\d+\s--\>\s(?<end>[\d\0:]+),.*\r\nHOME.*\r\nGPS\((?<x>[\d\.]+),(?<y>[\d\.]+),(?<d>[\d\.]+)\)\sBAROMETER\:(?<h>[\d\.]+)/'; 

$str= file_get_contents($srtFile); 
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0); 
echo '<pre>'; 
$filtered=array_map(function ($d){ 
    return $array_filtered = array_filter($d, "is_string", ARRAY_FILTER_USE_KEY); 
    },$matches); 
var_dump($filtered); 

, se siete interessati che cosa lo fa leggere i dati di posizione da un file str che droni DJI generano durante la registrazione vI deo.

Problemi correlati