Domanda

Voglio corrispondere un tag facoltativa alla fine di una riga di testo.

testo di input Esempio:

The quick brown fox jumps over the lazy dog {tag}

Voglio corrispondere alla parte in parentesi graffe e creare un back-riferimento ad esso.

I miei sguardi regex come questo:

^.*(\{\w+\})?

(un po 'semplificato, sto anche corrispondenti parti prima del tag):

Si abbina l'ok linee (con e senza il cartellino), ma non crea un back-riferimento al tag.

Se rimuovo il '?' carattere, quindi regex è:

^.*(\{\w+\})

Si crea un back-riferimento al tag, ma poi non corrisponde linee senza il cartellino.

ho capito da http://www.regular-expressions.info/refadv.html che l'operatore opzionale non inciderebbe sulla backreference:

  

Rotonda parentesi gruppo l'espressione regolare tra di loro. Catturano il testo di pari passo con l'espressione regolare al loro interno che può essere riutilizzato in un backreference, e permettono di applicare operatori regex a tutta la regex raggruppati.

, ma deve aver frainteso qualcosa.

Come faccio opzionale tag parte e creare un back-riferimento quando esiste?

È stato utile?

Soluzione

Non è un problema backreference, il problema è che l'espressione regolare è stato soddisfatto da solo leggendo nel testo che .* abbinato. Non si sentiva in dovere di continuare a leggere per leggere il tag di fine opzionale. La soluzione più semplice se stai veramente lettura alla fine della linea è quello di aggiungere un $ (simbolo di dollaro) per forzare l'espressione regolare per abbinare l'intera linea.

modifica

A proposito, non ho preso il tuo reg-ex letteralmente in quanto lei ha detto che soddisfa le altre cose, ma solo per essere chiari .* consumerà tutta la linea. Avresti bisogno di qualcosa come [^{]* per evitare che il tag di ottenere ingerito. Sto indovinando che non è un problema per voi.

Altri suggerimenti

In aggiunta a ciò che gli altri hanno spiegato, si potrebbe desiderare di fare il .* "pigro":

^.*?(\{\w+\})?

Come David Gladfelter detto, il vero problema è che quando si rendono facoltativa, che non corrisponde ; tuttavia, il suo fix proposto non funziona . Modifica 1: Avrai bisogno di utilizzare ciò che ha messo nella sua modifica (che ha ottenuto scritto come stavo scrivendo questo). Il problema è che i quantificatori (*, +, ?, {n,m}) sono avido : hanno sempre corrispondano quanto più possibile. Così, quando si scrive ^.*(\{\w+\})?, il .* corrisponde sempre tutta la linea, perché un vuoto soddisfa partita del gruppo opzionale. Si noti inoltre che, sebbene ? è avido, il primo greediness (di .*) ha la precedenza. Se ti è permesso solo per avere parentesi graffe intorno a quel gruppo opzionale, quindi è possibile risolvere il problema dicendo esplicitamente: ^[^\{]*(\{\w+\})?. In questo modo, il primo pezzo corrisponderà tutto fino alla prima parentesi graffa, e poi (dal ? è avido) se si può abbinare la parola riccio-parentesi.

Spesso, un altro modo per risolvere questo è quello di rendere i quantificatori pigro (o non-avido, minimal, etc.) aggiungendo un ?: *?, +?, ?? e {n,m}?. Tuttavia, questo non vi aiuterà qui: invece, se si fa ^.*?(\{\w+\})?, il .*? pigro cercherà di abbinare zero caratteri, avere successo, e quindi il gruppo opzionale non corrisponderà. Eppure, anche se non funziona qui, è uno strumento utile nella vostra cassetta degli attrezzi. Modifica 1:. Si noti inoltre che questi non sono disponibili in tutti i motori regex, anche se sono disponibili in C #

Grazie ragazzi. Ho usato una combinazione di risposte, il modificatore non-avidi e la partita di fine linea, che sembra fare il trucco, in modo da regex è ora:

^.*?(\{\w+\})?$ 

Non voleva usare [^ {] * per la prima parte della partita, come non-tag parentesi graffe possono apparire qui, ma i tag sarà sempre alla fine della linea.

Grazie per le risposte, erano tutti disponibili.

se siete interessati solo nel tag, e non si preoccupa il resto della stringa, allora si sarebbe rendere la vita molto più facile semplicemente corrispondenti al tag con questo regex ( vedere su rubular.com ):

\{(\w+)\}$

Questo è, si sta cercando di abbinare qualche {word} alla fine della stringa. Se non è lì, poi troppo male, non c'è alcuna corrispondenza. Non v'è alcuna necessità di un modificatore ? o un .* riluttante e tutta quella roba.

In C #, si potrebbe anche voler utilizzare RegexOptions.RightToLeft, dal momento che si sta cercando di abbinare un suffisso comunque, quindi forse qualcosa di simile:

string[] lines = {
  "The quick brown fox jumps over the lazy dog",
  "The quick brown fox jumps over the lazy dog {tag}",
  "The quick brown fox jumps over the {lazy} dog",
  "The quick brown fox jumps over the {lazy} {dog}",
};

Regex r = new Regex(@"\{(\w+)\}$", RegexOptions.RightToLeft);

foreach (string line in lines) {
  Console.WriteLine("[" + r.Match(line).Groups[1] + "]");
}

Questo stampa ( come visto in ideone.com ):

[]
[tag]
[]
[dog]
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top