2009-03-30 16 views
13

Devo creare un'espressione regolare che possa corrispondere a più stringhe. Ad esempio, voglio trovare tutte le istanze di "buono" o "grande". Ho trovato alcuni esempi, ma quello che mi è venuta non sembra funzionare:Regex per far corrispondere più stringhe

\b(good|great)\w*\b 

Qualcuno mi può puntare nella giusta direzione?

Modifica: Devo notare che non voglio solo abbinare parole intere. Ad esempio, potrei voler abbinare anche "ood" o "reat" (parti delle parole).

Modifica 2: Ecco alcuni esempi di testo: "Questa è davvero una grande storia." Potrei voler abbinare "questo" o "davvero", o potrei voler abbinare "eall" o "reat".

+1

Vuoi uguagliare anche "oo", "o" o "t"? – jpalecek

+3

Che dire di ooooooooooooooooooooooooooooooooooooooooooooooooooo? –

+0

Ho scoperto che usare "buono | bello" come funziona, è ok? Perché gli esempi di alcune persone hanno più markup in loro? –

risposta

21

Se si può garantire che non ci sono personaggi regex riservati nel vostro elenco di parole (o se li fuga), si potrebbe utilizzare questo codice per rendere a big word list in @"(a|big|word|list)". Non c'è niente di sbagliato con l'operatore | mentre lo stai usando, a patto che quelli () lo circondino. Sembra che lo \w* e gli schemi \b siano ciò che interferisce con le tue partite.

String[] pattern_list = whatever; 
String regex = String.Format("({0})", String.Join("|", pattern_list)); 
+1

Possibile errore: dovrebbe essere String.Join ("|", word_list) piuttosto che String.Join (word_list, "|"), vedere anche http://msdn.microsoft.com/en-us/library/57a79xd0 .aspx – David

+0

Buona cattura - grazie! Ho aggiornato la mia risposta. – ojrac

+1

Contrariamente alla domanda, non corrisponderà, per esempio, a "" ood "' in '" buono "'. – MikeM

4
(good)*(great)* 

dopo la modifica:

\b(g*o*o*d*)*(g*r*e*a*t*)*\b 
+0

Non corrisponderà aoooooooooooooooooooooooooooooooooooooooodddddddddddddddddddddddddddddd? –

+0

Sì, insieme a "gore", "gogogo" e un mucchio di altre combinazioni non volute. – Randy

0

non capisco il problema in modo corretto:

Se si desidera far corrispondere "grande" o "reat" si può esprimere questo da un modello come:

"g?reat" 

Questo semplicemente dice che la parte "reat" deve esistere e la "g" è opzionale.

Questo corrisponderebbe a "reat" e "grande" ma non a "mangiare", poiché è richiesta la prima "r" in "reat".

Se si hanno le anche parole "grande" e "buono" e si desidera far corrispondere entrambi con una "g" opzionale è possibile scrivere questo come questo:

(g?reat|g?ood) 

E se si desidera includere una parola-limite di simile:

\b(g?reat|g?ood) 

si deve essere consapevoli che questo non corrisponde a nulla di simile "breat", perché si ha la "reat", ma la "r" non è la parola di confine a causa della "B ".

Quindi, se si desidera far corrispondere le parole intere che contengono un link stringa "reat" o "ood" allora si dovrebbe provare:

"\b\w*?(reat|ood)\w+\b" 

Questo si legge: 1. Inizio con un limite di parola iniziare corrispondenza qualsiasi numero di caratteri-parola, ma non essere gready. 2. Corrispondenza "reat" o "ood" garantisce che solo quelle parole sono abbinate che contengono una di esse. 3. Corrisponde a qualsiasi numero di caratteri di parole che seguono "reat" o "ood" fino a raggiungere il limite di parola successivo.

Questo corrisponderà:

"bontà", "buono", "ood" (se una parola completa)

Può essere letto come: Dammi tutte le parole complete che contengono "ood" o "reat".

È quello che stai cercando?

1

Non sono del tutto sicuro che la regex offra solo una soluzione per quello che stai cercando di fare. Tuttavia, è possibile utilizzare il seguente codice per creare un'espressione regolare per una determinata parola. Anche se, l'espressione regolare risultante ha il potenziale per diventare molto lunga e lenta: Codice

function wordPermutations($word, $minLength = 2) 
{ 
    $perms = array(); 

    for ($start = 0; $start < strlen($word); $start++) 
    { 
     for ($end = strlen($word); $end > $start; $end--) 
     { 
      $perm = substr($word, $start, ($end - $start)); 

      if (strlen($perm) >= $minLength) 
      { 
       $perms[] = $perm; 
      } 
     } 
    } 

    return $perms; 
} 

prova:

$perms = wordPermutations('great', 3); // get all permutations of "great" that are 3 or more chars in length 
var_dump($perms); 

echo ('/\b('.implode('|', $perms).')\b/'); 

Esempio di output:

array 
    0 => string 'great' (length=5) 
    1 => string 'grea' (length=4) 
    2 => string 'gre' (length=3) 
    3 => string 'reat' (length=4) 
    4 => string 'rea' (length=3) 
    5 => string 'eat' (length=3) 

/\b(great|grea|gre|reat|rea|eat)\b/ 
1

ti penso stai chiedendo smth in realtà non intendi dire se vuoi cercare una parte di t lui parla, voi letteralmente cercando lettere

ad es. Cerca {Jack, Jim} in "John e Shelly sono cool"

è alla ricerca tutte le lettere nei nomi {J, A, C, K, E, M}

* J * ohn * un * nd Shelly * a * re

e per questo non è necessario REG-EX :)

a mio parere, un suffisso albero può aiutare con che

http://en.wikipedia.org/wiki/Suffix_tree#Functionality

divertirsi.

1

Basta controllare la booleana che restituisce Regex.IsMatch().

if (Regex.IsMatch(line, "condition") && Regex.IsMatch(line, "conditition2")) 

La linea avrà sia regex, giusto.

+0

L'elenco potrebbe contenere più di due parole e questo approccio non è ottimale. Inoltre, penso che devi solo abbinare una delle parole, il che significa che il tuo '&&' dovrebbe essere '||'. La risposta stessa ha avuto molti problemi con la formattazione, la sintassi e l'ortografia, che ho tentato di correggere. Si prega di rivedere le mie modifiche. –

Problemi correlati