2010-01-06 20 views
216

Sto cercando un modello che corrisponda a tutto fino a la prima occorrenza di un carattere specifico, ad esempio un ";" - a punto e virgola.Regex: corrispondenza fino alla prima occorrenza di un carattere

ho scritto questo:

/^(.*);/ 

Ma in realtà corrisponde a tutto (compreso il punto e virgola) fino a quando l'ultima occorrenza di un punto e virgola.

+40

'/^(.*?);' 'dovrebbe funzionare anche (si chiama ** non-avido **), ma le risposte fornite usando' [^;] * 'sono migliori. – Pascal

+0

come selezioneresti tutto, dopo il punto e virgola, e non il punto e virgola stesso. –

+0

vedere questo funziona '\ w + (?! ([^] +;) |;)' Ma questo non è il motivo? '. + (?! ([^] +;) |;)' –

risposta

326

È necessario

/[^;]*/ 

Il [^;] è una classe carattere, corrisponde a tutto, ma un punto e virgola.

di citare la perlre manpage:

È possibile specificare una classe di caratteri, racchiudendo un elenco di caratteri in [], che abbineranno ogni carattere dalla lista. Se il primo carattere dopo "[" è "^", la classe corrisponde a qualsiasi carattere non presente nell'elenco.

Questo dovrebbe funzionare nella maggior parte dei dialetti regex.

14

Prova /[^;]*/

Google regex character classes per i dettagli.

30

/^[^;]*/

Il [^;] dice corrisponde a nulla, tranne un punto e virgola. Le parentesi quadre sono un operatore di corrispondenza impostato, è essenzialmente, corrisponde a qualsiasi carattere in questo set di caratteri, lo ^ all'inizio lo rende una corrispondenza inversa, quindi corrisponde a qualsiasi cosa non in questo set.

+2

Si noti che il primo^in questa risposta assegna alla regex un significato completamente diverso: fa sì che l'espressione regolare ricerchi solo le corrispondenze che iniziano dall'inizio della stringa. In questo caso, sarebbe effettivamente un no-op * se * si esegue l'espressione regolare solo una volta. Se si desidera cercare più corrispondenze all'interno di una singola stringa, il primo^dovrebbe andare. –

+3

Ha detto che voleva abbinare tutto fino alla prima occorrenza di un punto e virgola, quindi ho pensato che intendesse dall'inizio della stringa. –

184

Would;

/^(.*?);/ 

lavoro?

Il ? è un operatore pigro, quindi l'espressione regolare afferra il meno possibile prima della corrispondenza dello ;.

+3

Sì, ricorda che TMTOWTDI è un moto perl :) :) http://en.wikipedia.org/wiki/TMTOWTDI –

+3

ya, ma seguendo l'estensione del bicarbonato a Tim Toady, credo che le classi di personaggi negate vincano come quantificatore pigro include il backtraking. +1 comunque. – Amarghosh

+2

Vale la pena leggere sull'argomento performance: http://blog.stevenlevithan.com/archives/greedy-lazy-performance –

5

questa non è una soluzione regolare, ma qualcosa di abbastanza semplice per la descrizione del problema. Basta dividere la stringa e ottenere il primo elemento dall'array.

$str = "match everything until first ; blah ; blah end "; 
$s = explode(";",$str,2); 
print $s[0]; 

uscita

$ php test.php 
match everything until first 
4

Questo è stato molto utile per me mentre stavo cercando di capire come abbinare tutti i personaggi in un tag XML inclusi gli attributi.Stavo correndo nella "corrisponde tutto fino alla fine" problema:

/<simpleChoice.*>/ 

ma era in grado di risolvere il problema con:

/<simpleChoice[^>]*>/ 

dopo la lettura di questo post. Ringrazia tutti.

+0

Avevo scoperto che è molto più efficiente analizzare effettivamente (ogni lingua o framework ha le sue classi per quello) html/xml a causa del suo formato macchina, regex sono per linguaggio naturale. –

+0

Bello. L'ho usato per correggere i documenti xml con errori di sintassi nel tag ''. Dal momento che parser non era in grado di gestirlo. –

5
testo

di esempio:

"this is a test sentence; to prove this regex; that is g;iven below" 

Se per esempio abbiamo il testo di esempio sopra, l'espressione regolare /(.*?\;)/ vi darà tutto fino alla prima occorrenza di punto e virgola (;), tra cui il punto e virgola: "this is a test sentence;"

+1

non è necessario uscire da ';' perché non è regex carattere speciale. Anche il raggruppamento '()' non è richiesto. Puoi andare con '/.*?;/' –

+0

sì, hai perfettamente ragione. la fuga era più come "meglio prevenire che curare" – poncius

+1

Questa è la risposta che stavo cercando. Così il ? fa finire la partita alla prima apparizione? Qual è il nome di questa ... (chiamiamola) proprietà della regex? – Parziphal

3

"/^([^\/]*)\/$/" ha funzionato per me, per ottenere solo le "cartelle" principali da un array come:

a/ <- this 
a/b/ 
c/ <- this 
c/d/ 
/d/e/ 
f/ <- this 
2

Davvero un po 'triste che nessuno ti abbia dato la risposta corretta ....

In espressioni regolari,? lo rende non avido. Per impostazione predefinita, regex corrisponderà il più possibile (avido)

Basta aggiungere un? e sarà non avido e abbinerà il meno possibile!

Buona fortuna, spero che ti aiuti.

+2

Questo dipende in gran parte dall'implementazione regex ** ** e non tutte le implementazioni hanno una modalità non avida. – karatedog

1

Questo corrisponderà fino alla prima occorrenza solo in ciascuna stringa e ignorerà le occorrenze successive.

/^([^;]*);*/ 
Problemi correlati