2009-09-10 9 views
5

Estoy tratando de tener algún tipo de objeto de datos (estoy pensando en un diccionario) para mantener una tonelada de expresiones regulares como claves, entonces tengo que tomar una cadena de texto, y partido contra ellos para obtener el valor real del Diccionario. Necesito una manera eficiente de hacer esto para un gran conjunto de datos.Coincidir expresión regular de un diccionario en C#

Estoy en C# y no estoy seguro de por dónde empezar.

+0

Basado en las respuestas hasta ahora, es posible que desee proporcionar más detalles en su pregunta sobre su aplicación en particular. –

+1

¿Aproximadamente cuántas expresiones hay en una tonelada? ¿Qué tan grande es el texto que van a coincidir? ¿Con qué frecuencia se proporcionará un nuevo texto? ¿Qué tan rápido deben devolverse los resultados? – TrueWill

Respuesta

7

¿Por qué no utilizar LINQ?

Dictionary<string, string> myCollection = new Dictionary<string, string>(); 

myCollection.Add("(.*)orange(.*)", "Oranges are a fruit."); 
myCollection.Add("(.*)apple(.*)", "Apples have pips."); 
myCollection.Add("(.*)dog(.*)", "Dogs are mammals."); 
// ... 

string input = "tell me about apples and oranges"; 

var results = from result in myCollection 
       where Regex.Match(input, result.Key, RegexOptions.Singleline).Success 
       select result; 

foreach (var result in results) 
{ 
    Console.WriteLine(result.Value); 
} 

// OUTPUT: 
// 
// Oranges are a fruit. 
// Apples have pips. 
+0

Voy a comenzar con esta solución, hasta ahora funciona bastante rápido con un diccionario de aproximadamente 500 elementos. Si empeora, buscaré otras alternativas. ¡Gracias! –

0

No estoy seguro de si realmente necesita expresiones regulares para esto - podría usar un trie. Representar diccionarios es una aplicación común para un trie. (Supongo que te refieres a un diccionario como en una lista de palabras, y no al significado de "matriz asociativa").

0

¿Quiere decir unir una cuerda contra las expresiones regulares para obtener una coincidencia de expresiones regulares? ¿O solo una coincidencia de texto? En otras palabras, ¿la cadena que va a ser SERÁ una de esas expresiones regulares, o algunos datos para APLICAR una expresión regular?

Si es una expresión regular y desea encontrarla en la lista, no necesita un diccionario, son contenedores de 2 partes. Podrías usar una Lista o una Colección de cadenas, y preguntar por IndexOf (mytString), -1, lo que significa que no está ahí.

0

Si sus expresiones regulares no son triviales individuales cuerdas, y que se preocupan por la eficiencia, que querría que los represente en una sola NFA (nondeterministic finite-state automaton, con valores en los estados finales. Si es posible que una entrada coincida con más de una expresión regular, los estados finales necesitarían un conjunto de valores.

En este punto, está preparado para considerar la optimización del autómata. Si se puede determinar de forma práctica (esto le da un DFA que puede ser exponencialmente más grande que el NFA), entonces, por supuesto, haga eso. Una vez que tiene un DFA, puede minimizarlo de manera eficiente (y únicamente hasta el isomorfismo) (pero dado que tiene valores en sus estados finales, se necesita una modificación obvia del usual algorithm).

También hay técnicas para minimizar NFA directamente. Por ejemplo, si dos estados tienen los mismos conjuntos de sufijos ({(resto de cadena, valor)}) son equivalentes y se pueden combinar. La equivalencia en un NFA acíclico puede realizarse a través del hash-consing a partir de los estados finales.

0

Recuerde que si planea usar una expresión regular más de una vez, puede crear un objeto de expresión regular compilado y reutilizarlo para reducir la sobrecarga.

Regex RegexObject = new Regex(Pattern, RegexOptions.Compiled); 

Con este modelo, sería mejor almacenar un objeto de expresión regular en lugar de la cadena de diseños.

Cuestiones relacionadas