2011-09-09 17 views
8

voglio un'espressione regolare per abbinare tutti questi:regex lookahead opzionale

  1. startabcend
  2. startdef
  3. blahstartghiend
  4. blahstartjklendsomething

e tornare abc, def, ghi e jkl rispettivamente.

Ho questo il seguente che funziona per il caso 1 e 3 ma sto avendo problemi a rendere il lookahead opzionale.

(?<=start).*(?=end.*) 

Edit:

Hmm. Cattivo esempio In realtà, il bit nel mezzo non è numerico, ma è preceduto da un certo insieme di caratteri e può essere opzionalmente seguito da esso. Ho aggiornato gli input e gli output come richiesto e ho aggiunto un quarto esempio in risposta alla domanda di qualcuno.

risposta

8

Cercando di leggere tra le righe, sembra che forse non si vuole lookahead qui, si vuole realmente non avido .*?.

(?<=start).*?(?:end)?$ 

La mia ipotesi è che si sta cercando di abbinare contro qualcosa come "start123end", ma non si desidera che il end o start di presentarsi nel testo corrispondente, e quindi si hanno le affermazioni Lookaround lì per vincolare il .* che è normalmente avido.

Invece, puoi semplicemente usare la variante non-golosa e ancorare l'estremità destra del modello con uno $.

(In alternativa, se si è in grado di utilizzare gruppi di cattura, si dovrebbe fare solo che invece:

start(.*?)(end)?$ 

e poi basta ottenere il valore dal primo gruppo di cattura.)

1

Un lookahead facoltativa non ha senso:

Se è opzionale, allora è ok se corrisponde, ma è anche ok, se non corrisponde. E poiché un lookahead non estende la partita, non ha assolutamente alcun effetto.

Quindi la sintassi per un lookahead opzionale è la stringa vuota.

+0

Ho bisogno di restituire il bit nel mezzo senza il suffisso opzionale. –

+0

Quindi dovresti abbinare 'start456otherstuff'? –

+0

no, ma dovrebbe corrispondere a start456endotherstuff ma restituire solo 456. –

0

Perché hai bisogno di guardare avanti?

start(\d+)\w* 

vedere sul rubular

5

Forse in questo modo:

(?<=start).*?(?=(?:end|$)) 

Ciò corrisponderà fino a "start" e "fine" o fino alla fine della linea, inoltre il quantificatore deve essere non avido (.*?)

See it here on Regexr

Esteso l'esempio su Regexr non solo per lavorare con cifre.

2

Lookahead da solo non farà il lavoro. Prova questo:

(?<=start)(?:(?!end).)* 

Le posizioni voi lookbehind dopo la parola "inizio", poi il resto di esso consuma tutto fino (ma non compreso) la prossima occorrenza di "fine".

Ecco un demo on Ideone.com

1

se "fine" sta andando sempre essere presente, quindi utilizzare: (?<=start)(.*?)(?=end) come si mette nel PO. Dal momento che dici "rendere il lookahead opzionale", esegui semplicemente fino a quando non viene visualizzata la "fine" o il ritorno a capo. (?<=start)(.*?)(?=end|\n). Se non ti interessa catturare il gruppo "fine", puoi saltare il lookahead e fare (?:start)?(.*?)(?:end)? che inizierà dopo "start", se è lì e fermarsi prima di "end", se è lì. È inoltre possibile utilizzare più di questi modelli "o" convogliati: (?:start|^) e (?:end|\n).