Domanda

Come si potrebbe scrivere un regex che corrisponde a un modello che può contenere le citazioni, ma se lo fa, deve avere le virgolette all'inizio e alla fine di corrispondenza?

"?(pattern)"?

non funzionerà perché permetterà modelli che iniziano con una citazione, ma non terminano con uno.

"(pattern)"|(pattern)

funzionerà, ma è ripetitivo. C'è un modo migliore per farlo senza ripetere lo schema?

È stato utile?

Soluzione

È possibile ottenere una soluzione senza ripetere facendo uso di backreference e condizionali :

/^(")?(pattern)(?(1)\1|)$/

Partite:

  • modello
  • "modello"

Mancata corrispondenza:

  • "modello
  • pattern "

Questo modello è un po 'complessa, tuttavia. Prima si cerca una citazione optional, e lo mette in backreference 1 se ne viene trovato uno. Poi cerca il vostro modello. Poi si utilizza la sintassi condizionale per dire "se backreference 1 si ritrova, corrisponde, altrimenti corrispondere nulla". L'intero modello è ancorato (che significa che deve comparire da solo su una riga) in modo che le virgolette non saranno catturati (in caso contrario la pattern in pattern" sarebbe partita).

Si noti che il supporto per i condizionali varia a seconda del motore e il più prolisso, ma espressioni ripetitive saranno più ampiamente supportati (e probabilmente più facile da capire).


Aggiornamento: Una versione molto più semplice di questo regex sarebbe /^(")?(pattern)\1$/, che non ha bisogno di un condizionale. Quando stavo testando questo inizialmente, il tester usavo mi ha dato un falso negativo, che mi portano allo sconto (oops!).

lascio la soluzione con il up condizionale per i posteri e interesse, ma questa è una versione più semplice che è più probabile che il lavoro in una più ampia varietà di motori (backreference sono l'unica caratteristica in uso qui che potrebbe essere supportato) .

Altri suggerimenti

A seconda della lingua che si sta utilizzando, si dovrebbe essere in grado di utilizzare backreference. Qualcosa di simile, ad esempio:

(["'])(pattern)\1|^(pattern)$

In questo modo, si sta richiedendo che o non ci sono le citazioni, o che la citazione STESSO viene utilizzato su entrambe le estremità.

Questo dovrebbe funzionare con regex ricorsiva (che ha bisogno di più tempo per arrivare a destra). Nel frattempo: in Perl , è possibile costruire un automodificante regex . Lascio che come esempio accademica; -)

my @stuff = ( '"pattern"', 'pattern', 'pattern"', '"pattern'  );

foreach (@stuff) {
   print "$_ OK\n" if /^
                        (")?
                        \w+
                        (??{defined $1 ? '"' : ''})
                       $
                      /x
}

Risultato:

"pattern" OK
pattern OK
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top