2013-09-05 12 views
5

Ho tentato di convalidare una stringa in VB.net che deve contenere queste tre lettere in un ordine particolare e non è necessario che siano l'una accanto all'altra. ABCIl regex deve contenere lettere specifiche in qualsiasi ordine

posso farlo facilmente utilizzando LINQ

MessageBox.Show(("ABC").All(Function(n) ("AAAABBBBBCCCC").Contains(n)).ToString) 

Tuttavia, dopo la ricerca di Google e così per oltre una settimana, io sono completamente confusi. Il mio modello più simile è ".*[A|B|C]+.*[A|B|C]+.*[A|B|C]+.*" come sempre AAA restituirebbe anche true. So che posso farlo usando altri metodi solo dopo aver provato per una settimana, voglio davvero sapere se è possibile usare un'espressione regolare.

+1

C'è un motivo per cui è necessario Regex? Ed è sempre solo un set di 3 personaggi? – user7116

+0

Sto cercando di imparare come usare espressioni regolari. Per imparare Uno deve impostare compiti per se stesso. Grazie per aver trovato il tempo di rispondere :) –

+0

Potresti provare un altro problema per l'apprendimento della regex. Mentre è possibile risolvere questo, come ha mostrato Jerry, non è un problema particolarmente buono per un'espressione regolare (molte librerie di stringhe offrono persino un metodo 'ContainsAll'). – ssube

risposta

4

vostro modello originale non funziona perché sarà adattarsi a qualsiasi numero di caratteri, seguito da uno o più A, B, C o | carattere, seguito da un numero qualsiasi di caratteri, seguito da uno o più A, B , C o |, seguito da un numero qualsiasi di caratteri, seguito da uno o più caratteri A, B, C o |, seguito da un numero qualsiasi di caratteri.

probabilmente sarei andare con il codice che hai già scritto, ma se si vuole veramente per usare un'espressione regolare, è possibile utilizzare una serie di lookahead assertions, in questo modo:

(?=.*A)(?=.*B)(?=.*C) 

Ciò corrisponderà qualsiasi stringa contenente A, B e C in qualsiasi ordine.

+0

Grazie per aver dedicato del tempo a spiegare il mio modello e fornire un esempio. –

+0

Dovresti menzionare che i lookaheads sono corrispondenze di larghezza zero e dovrebbero essere seguiti da un pattern su cui confrontarsi (es. '. +' Seguendo i lookaheads): '(? =. * A) (? =. * B) (? =. * C). + ' – bobobobo

+1

@bobobobo Non necessariamente. Una stringa di lunghezza zero è un modello valido, quindi se stai solo testando una corrispondenza (e non ti interessa catturare effettivamente una corrispondenza), solo l'asserzione di larghezza zero funziona correttamente. Vedi https://repl.it/repls/BumpyFoolhardyBarnswallow –

6

È possibile fare uso di lookaheads positivi:

^(?=.*A)(?=.*B)(?=.*C).+ 

(?=.*A) rende sicuro che c'è una A da qualche parte nella stringa e la stessa logica vale per gli altri lookaheads.

+0

Oh mio Dio. Quanto vicino non ero. Capisco il raggruppamento ma ti dispiacerebbe spiegarlo (? = È quello il look positivo a testa? –

+0

@SamJohnson Yup! È una sintassi regex un po '"avanzata" se me lo chiedi. Mi ci sono voluto un po' per capirli Fondamentalmente, si otterrà una corrispondenza solo se la condizione tra parentesi è abbinata, quindi, se la stringa corrisponde a '. * A' (cioè qualsiasi carattere, quindi un' A', corrisponderà). che in una fila è come controllare 3 condizioni e assicurarsi che siano soddisfatti prima di continuare ulteriormente.Questa è una descrizione approssimativa del lookahead, ma è possibile ottenere maggiori informazioni [qui] (http://www.regular-expressions.info/ lookaround.html). – Jerry

+0

Grazie mille per il tuo tempo e per il tuo impegno Ho accettato la tua risposta Lo apprezzo davvero –

0

Dev'essere una regex? È qualcosa che può essere facilmente risolto senza uno.

Non ho mai programmato in VB, ma sono sicuro che ci sono funzioni di supporto che consentono di prendere una stringa e interrogare se un carattere si verifica o meno in esso.

Se str è la stringa, forse qualcosa di simile:

str.contains ('A') & & str.contains ('B') & & str.contains ('C')

+2

"Deve essere un'espressione regolare? È qualcosa che può essere facilmente risolto senza uno." Non ho già fornito un esempio funzionante che non utilizza regex? –

0

È possibile utilizzare lookaheads zero-width. I lookheadhead sono ottimi per eliminare le possibilità di abbinamento se non soddisfano determinati criteri.

Per esempio, usiamo le parole

untie queue unique block unity 

Inizia con un fiammifero la parola di base:

\b\w+\b 

di richiedere la parola abbinato \w+ inizia con un, potremmo usare un positiva lookahead

\b(?=un)\w+\b 

cosa dice questo è

  • \b Partita un vuoto
  • (?=un) Ci sono le lettere "UN"? In caso contrario, NO MATCH. Se è così, allora la possibile corrispondenza.
  • \w+ Uno o più caratteri alfanumerici
  • \b Incontro un vuoto

Un lookahead positivo elimina una possibilità incontro se non soddisfa l'espressione contenuta. Si applica alla regex DESTRO dopo. Quindi lo (?=un) si applica all'espressione \w+ precedente e richiede che COMINCIA CON . In caso contrario, l'espressione \w+ non corrisponderà.

Che tipo di abbinamento di parole che non inizi con un? Basta usare un "lookahead negativo"

\b(?!un)\w+\b 
  • \b Partita un vuoto
  • (?!un) vi sono le lettere "UN"? Se SO, NESSUNA PARTITA. In caso contrario, quindi possibile corrispondenza.
  • \w+ uno o più word caratteri
  • \b Incontro un vuoto

Quindi per la vostra esigenza di avere almeno 1 A, 1 B e 1 C della stringa, un modello come

(?=.*A)(?=.*B)(?=.*C).+ 

funziona perché dice:

  • (?=.*A) - Fa i t hanno .* qualsiasi carattere seguito da A? Se è così, è possibile una corrispondenza se non c'è una corrispondenza.
  • (?=.*B) - Ha .* qualsiasi carattere seguito da B? Se è così, è possibile una corrispondenza se non c'è una corrispondenza.
  • (?=.*C) - Ha .* qualsiasi carattere seguito da C? Se è così, è possibile una corrispondenza se non c'è una corrispondenza.
  • .+ Se i requisiti di lookahead di cui sopra sono stati soddisfatti, corrisponde a qualsiasi carattere. In caso contrario, non corrispondono caratteri (e quindi non c'è corrispondenza)
Problemi correlati