2010-08-23 15 views
5

Diciamo che sto cercando di abbinare /dog.*lab/ contro questo testo:Regex ungreedy dal lato sinistro (vale a dire, più stretta corrispondenza possibile da entrambi i lati)

"Ho un cane Il mio cane è un laboratorio di nero.. È stato creato in un laboratorio. "

Avidamente, corrisponde a "dog. Il mio cane è un laboratorio nero.E 'stato creato in un laboratorio".

Desidero trovare le corrispondenze più strette da entrambi i lati. Se uso il modificatore ungreedy come
/dog.*?lab/ o /dog.*lab/U si avrà meno ma ancora troppo:
"Cane Il mio cane è un laboratorio nero"

C'è un modo per rendere la mia ricerca ungreedy dal lasciato anche, quindi corrispondente solo "dog is a black lab"?

Grazie mille. Ci scusiamo per l'esempio inventato.

+0

Cosa succede se l'input è "" dog123lab dog12lab dog1lab "'? Vuoi saltare tutti gli altri e solo ottenere 'dog1lab' dato che è la partita più piccola possibile? – polygenelubricants

+0

@polygenelubricants No, vorrei che fossero tre partite separate. Penso che sarei stato più preciso nel chiedere la corrispondenza _narrowest_, non la _smallest_. Grazie. – Wiseguy

risposta

10

si potrebbe usare un look-ahead assertion che esclude la presenza di dog tra dog e lab:

/dog(?:(?!dog).)*?lab/ 
+1

@polygenelubrificanti: Oh sì, certo. Grazie per l'osservazione. – Gumbo

+0

Questo richiede un po 'più di pre-elaborazione logica per preparare la mia parola chiave (s) per la ricerca regex, ma funziona perfettamente. Grazie per l'info. – Wiseguy

1

Un'idea potrebbe essere quella di cercare di utilizzare un set di caratteri negata, come [^.!?], che dovrebbe corrispondere tutti i caratteri tranne ., ? e !, e quindi si può essere sicuri che sia all'interno della stessa frase:

$string = "I have a dog. My dog is a black lab. He was created in a laboratory."; 
preg_match('/dog[^.!?]*?lab/', $string, $match); 
echo $match[0]; // Echoes "dog is a black lab" 
+0

Grazie. Questo è vero, ma non posso garantire nella mia domanda che la corrispondenza richiesta sia all'interno di una frase o riga. – Wiseguy

2

questo funziona per me:

$str = "I have a dog. My dog is a black lab. He was created in a laboratory."; 
if(preg_match('/.*(dog.*?lab)/',$str,$m)) { 
    var_dump($m); 
} 
+0

Non sono sicuro del motivo per cui questo è stato down-votato. Questa idea è sana. Per forzare la partita non avida ad essere il più piccola possibile, metti immediatamente una ricerca avida di fronte ad essa e poi ispeziona il gruppo di cattura. – Andrew

+1

@Andrew, @codaddict: il downvote non è venuto da me, ma si riferisce all'ultimo commento di OP riguardo al volere più corrispondenze. Questo troverà solo l'ultima partita. – polygenelubricants

+1

L'ultima partita non è sempre la partita più piccola. È per * questa * stringa di test, ma non è difficile trovare una stringa in cui la più piccola corrispondenza sia effettivamente nel mezzo o all'inizio. –

Problemi correlati