2009-08-11 13 views
6

Vorrei testare se un'espressione regolare corrisponde a una parte di una stringa in un indice specifico (e solo a partire da quell'indice specifico). Ad esempio, data la stringa "uno due 3 4 cinque", mi piacerebbe sapere che, con l'indice 8, l'espressione regolare [0-9] + corrisponderà a "3". RegularExpression.IsMatch e Match hanno entrambi un indice iniziale, ma entrambi cercheranno l'intero resto della stringa per una corrispondenza, se necessario.corrispondenza di espressione regolare C# a indice specifico nella stringa?

string text="one two 3 4 five"; 
Regex num=new Regex("[0-9]+"); 

//unfortunately num.IsMatch(text,0) also finds a match and returns true 
Console.WriteLine("{0} {1}",num.IsMatch(text, 8),num.IsMatch(text,0)); 

Ovviamente, ho potuto verificare se la partita risultante inizia l'indice Sono interessato a, ma io cercherò di fare di questo un gran numero di volte su stringhe di grandi dimensioni, in modo da non voglio perdere tempo a cercare per le partite successive nella stringa. Inoltre, non saprò in anticipo quali sono le espressioni regolari che effettivamente testerò contro la stringa.

io non voglio:

  1. dividere la stringa su alcuni confine come spazi bianchi perché nella mia situazione non voglio sapere in anticipo che cosa un confine adatto sarebbe
  2. devono modificare la stringa di input in qualsiasi modo (come ottenere la stringa all'indice 8 e quindi utilizzando^nella regex)
  3. cercare il resto della stringa per una stuoia ch o fare qualcosa altro che non sarebbe performante per un gran numero di prove contro una stringa grande .

Vorrei analizzare un corpo di testo potenzialmente grande fornito dall'utente utilizzando una grammatica fornita dall'utente arbitrario. La grammatica sarà definita in una sintassi simile a BNF o PEG e i terminali saranno sia letterali stringa che espressioni regolari. Quindi dovrò verificare se la parte successiva della stringa corrisponde a uno qualsiasi dei potenziali terminali come guidato dalla grammatica.

+1

Puoi spiegare cosa stai cercando di fare in senso lato? Le tue restrizioni su ciò che non vuoi fare sono confuse. –

+0

Ho aggiunto una breve descrizione di ciò che sto facendo. Inoltre, i requisiti si riducono a: Non voglio fare nulla di lento e non ho una conoscenza approfondita di ciò che sto cercando di analizzare in anticipo. – Rngbus

risposta

11

Come utilizzare Regex.IsMatch(string, int) utilizzando un'espressione regolare che inizia con \G (che significa "inizio dell'ultima partita")?

che sembra funzionare:

using System; 
using System.Text.RegularExpressions; 

class Test 
{ 
    static void Main() 
    { 
     string text="one two 3 4 five"; 
     Regex num=new Regex(@"\G[0-9]+"); 

     Console.WriteLine("{0} {1}", 
          num.IsMatch(text, 8), // True 
          num.IsMatch(text, 0)); // False 
    } 
} 
+0

Interessante, se c'è un modo per impostare artificialmente l'ultima posizione della partita, allora potrebbe funzionare. Altrimenti non credo che mi sarà d'aiuto perché salterò tra diverse espressioni regolari e luoghi diversi. – Rngbus

+0

Ho avuto la possibilità di provare questo e sembra fare esattamente quello che voglio. Tratta l'indice di inizio passato come "inizio dell'ultima partita" indipendentemente da dove si trovasse effettivamente l'ultima partita. Perfetto grazie! – Rngbus

+2

E per aggiungere un po 'di informazioni per chiunque abbia questo problema, http://www.regular-expressions.info/continue.html descrive l'ancora \ G. Sembra indicare "inizio dell'ultima partita" o "inizio del tentativo di incontro" a seconda dell'implementazione. In alcune implementazioni probabilmente non risolverà questo problema, ma sembra essere "inizio del tentativo di abbinamento" in C# e funziona bene per la corrispondenza in una posizione specifica. – Rngbus

2

Se si desidera cercare una sottostringa del testo, afferrare quel sottostringa prima della regex unico.

myRegex.Match(myString.Substring(8, 10)); 
+2

Vedere il punto 2 nella domanda. –

+0

Non sembra che questo modifichi la stringa di input, quindi +1. Se il punto 2 non riguarda solo la modifica della stringa di input, deve essere modificato. – ojrac

+1

Bene, sta modificando l'input * con l'espressione regolare *. Dato il "fare questo un gran numero di volte su stringhe grandi" non avrei pensato che una sottostringa fosse una soluzione ideale. –

1

io non sono sicuro di aver capito pienamente la domanda, ma mi sembra che si può semplicemente fare la parte posizione della espressione regolare, per esempio

^.{8}[\d] 

che corrisponderà se ci sono 8 caratteri tra l'inizio della stringa e una cifra.

+1

Questo non è l'ideale, perché comporterebbe la modifica dell'espressione regolare per ogni posizione in cui voglio testare. Dipende anche dalla regex che è abbastanza intelligente da ottimizzare ^. {8} in qualcosa che salta immediatamente alla posizione 8. – Rngbus

0

Se si conosce la lunghezza massima di una corrispondenza potenziale nella stringa da controllare si limita la scansione della stringa.

Se si stanno verificando solo i numeri, è probabilmente più semplice che controllare le espressioni arbitrarie. La natura di Regex è di scansionare fino alla fine per trovare una corrispondenza. Se si desidera impedire la scansione è necessario includere una lunghezza o utilizzare qualcosa di diverso da Regex.

string text = "one two 3 4 five"; 
Regex num = new Regex("[0-9]+"); 
int indexToCheck = 8; 
int maxMatchLength = ...; 
Match m = num.Match(text, indexToCheck, maxMatchLength); 

Sai qualcosa su quali tipi di espressioni potrebbe essere eseguito contro le corde, e sarà la scansione dell'intera stringa di essere troppo di un overhead?

num.Match restituirà il primo hit se esiste, quindi interromperà la scansione. Se desideri più corrispondenze, chiamerai m.NextMatch() per continuare la scansione delle corrispondenze.

+0

Purtroppo non so quali saranno le espressioni regolari in anticipo e non posso fornire una lunghezza massima diversa dal resto della stringa. – Rngbus

+0

L'espressione da trovare potrebbe avere una lunghezza variabile, a seconda degli spazi, ad es. iniziano le nuove linee e il paragrafo rientrato, o qualsiasi altra cosa. – ProfK

Problemi correlati