2013-06-06 23 views
9

Ecco la mia stringa:Regex - Ignora alcune parti della stringa in partita

address='St Marks Church',notes='The North East\'s premier...' 

L'espressione regolare che sto usando per afferrare le varie parti utilizzando match_all è

'/(address|notes)='(.+?)'/i' 

I risultati sono:

indirizzo => St Marks Church
note => The North East \

Come posso far sì che ignori il carattere \ 'per le note?

+1

Vorresti considerare solo caratteri alfanumerici nella tua espressione? –

+0

No fondamentalmente nulla tra 'e il secondo' escluso \ '. Sono un po 'un newbie regex, temo che probabilmente anche il primo bit abbia sbagliato? –

risposta

4
Non

sicuro se si sta avvolgendo la stringa con heredoc o doppi apici, ma un approccio meno avido:

$str4 = 'address="St Marks Church",notes="The North East\'s premier..."'; 
preg_match_all('~(address|notes)="([^"]*)"~i',$str4,$matches); 
print_r($matches); 

uscita

Array 
(
    [0] => Array 
     (
      [0] => address="St Marks Church" 
      [1] => notes="The North East's premier..." 
     ) 

    [1] => Array 
     (
      [0] => address 
      [1] => notes 
     ) 

    [2] => Array 
     (
      [0] => St Marks Church 
      [1] => The North East's premier... 
     ) 

) 

Un altro metodo con preg_split:

//split the string at the comma 
//assumes no commas in text 
$parts = preg_split('!,!', $string); 
foreach($parts as $key=>$value){ 
    //split the values at the = sign 
    $parts[$key]=preg_split('!=!',$value); 
    foreach($parts[$key] as $k2=>$v2){ 
     //trim the quotes out and remove the slashes 
     $parts[$key][$k2]=stripslashes(trim($v2,"'")); 
    } 
} 

L'output è simile a:

Array 
(
    [0] => Array 
     (
      [0] => address 
      [1] => St Marks Church 
     ) 

    [1] => Array 
     (
      [0] => notes 
      [1] => The North East's premier... 
     ) 

) 

Super lento metodo di vecchia scuola:

$len = strlen($string); 
$key = ""; 
$value = ""; 
$store = array(); 
$pos = 0; 
$mode = 'key'; 
while($pos < $len){ 
    switch($string[$pos]){ 
    case $string[$pos]==='=': 
     $mode = 'value'; 
     break; 
    case $string[$pos]===",": 
     $store[$key]=trim($value,"'"); 
     $key=$value=''; 
     $mode = 'key'; 
     break; 
    default: 
     $$mode .= $string[$pos]; 
    } 

    $pos++; 
} 
     $store[$key]=trim($value,"'"); 
+0

Il primo metodo regola la stringa di input per adattarsi al metodo, questo metodo deve essere rimosso. Il secondo usa 'preg_split()' dove 'explode()' è la chiamata della funzione sensibile. Inoltre, se '\ '' è possibile nella stringa, allora è corretto assumere anche ',' e '='. Il terzo, non ho ancora testato ma ha un errore di battitura o utilizza variabili variabili che dovrebbero essere evitate quando possibile. – mickmackusa

+0

Ho rimosso il mio downvote perché apprezzo che tu stia cercando di correggere la tua risposta. Tristemente, sento che ho dovuto ridiscendere perché questa risposta suggerisce metodi poveri e/o inaffidabili. – mickmackusa

+0

Non è mai consigliabile effettuare concessioni per metodi di archiviazione dati non validi.Questo flusso di testo deve essere memorizzato in JSON, XML o anche CSV ed elaborato idealmente con i metodi standard del settore. Apprezzo la tua opinione però. –

1

Si dovrebbe corrispondere ad un preventivo finale che non è preceduto da un backslash così:

(address|notes)='(.*?)[^\\]' 

Questa [^\\] costringe il carattere immediatamente precedente il 'carattere di essere tutt'altro che una barra rovesciata.

+0

Funzionerà se l'input è: "" address = '.', Notes = 'Il premier del Nord Est ...' "'? – anubhava

+0

Come alluso a @anubhava, questa risposta non è corretta e mancherà i valori di ritorno previsti. https://regex101.com/r/90fBSr/1 (downvoted come fuorviante) – mickmackusa

1

Perché avete pubblicato che si sta utilizzando match_all ei tag top nel tuo profilo è php e wordpress, penso che sia giusto presumere che si sta utilizzando preg_match_all() con php.

I abbinare le sottostringhe richiesti seguenti modelli di buildyour desiderati array associativo:

modelli che generano una corrispondenza fullstring e gruppo 1 cattura:

  1. /(address|notes)='\K(?:\\\'|[^'])*/ (166 gradini, demo link)
  2. /(address|notes)='\K.*?(?=(?<!\\)')/ (218 gradini, demo link)

modelli che generano 2 gruppi di cattura:

  1. /(address|notes)='((?:\\\'|[^'])*)/ (168 gradini, demo link)
  2. /(address|notes)='(.*?(?<!\\))'/ (209 gradini, demo link)

Codice: (Demo)

$string="address='St Marks Church',notes='The North East\'s premier...'"; 

if(preg_match_all("/(address|notes)='\K(?:\\\'|[^'])*/",$string,$out)){ 
    $result=array_combine($out[1],$out[0]); 
} 
var_dump($result); 

echo "\n---\n"; 

if(preg_match_all("/(address|notes)='((?:\\\'|[^'])*)/",$string,$out,PREG_SET_ORDER)){ 
    $result=array_combine(array_column($out,1),array_column($out,2)); 
} 
var_dump($result); 

uscita:

I modelli 1 e 3 utilizzano alternative per consentire caratteri non apostrofo o apostrofi non preceduti da una barra rovesciata.

Gli schemi n. 2 e n. 4 (richiedono una barra rovesciata aggiuntiva se implementato con php demo) utilizzano i metodi di ricerca per garantire che gli apostrofi preceduti da una barra rovesciata non interrompano la corrispondenza.

Alcune note:

  • Utilizzando i gruppi di cattura, le alternative, e lookarounds costa efficienza modello. Limitare l'uso di questi componenti migliorerà le prestazioni. L'utilizzo di classi di caratteri negati spesso migliora le prestazioni.

  • L'utilizzo di \K (che riavvia la corrispondenza fullstring) è utile quando si tenta di ridurre i gruppi di cattura e si riduce la dimensione della matrice di output.

+0

@PaulPhillips oltre 4 anni dopo, potresti non essere più un principiante alle espressioni regolari. Si prega di rivedere tutte le risposte su questa pagina. Purtroppo le altre risposte in questa pagina sono imprecise/errate e hanno accumulato upvotes nel tempo (il che significa che hanno disinformato i lettori per anni). Se avete domande sulla mia risposta o perché le altre risposte non sono corrette, sarò felice di spiegare. – mickmackusa

+0

Hey Mick stai trollando le risposte precedenti di tutti o solo il mio? –

+0

Mi sono imbattuto in questa pagina mentre cercavo un'altra domanda su un altro sito StackExchange. Non c'è niente di strano sulla mia condotta. Se volessi essere un troll, ti chiamerei semplicemente o semplicemente non lascerei un commento. No, quello che ho fatto è stato identificato in una pagina che conteneva 3 risposte sbagliate (ora 2 dopo anubhava cancellato), ha erroneamente ridimensionato le risposte sbagliate che disinformavano, lasciato commenti esplicativi (con link dimostrativi), modificato la domanda e fornito un esauriente e premuroso risposta. Quello che ho fatto dovrebbe essere considerato solo "miglioramento del contenuto". – mickmackusa

Problemi correlati