2015-12-30 9 views
1

Dans une chaîne d'entrée, je souhaite utiliser le Jagged Array suivant pour remplacer la première valeur de colonne par la deuxième colonne précédée de \. Par exemple, a<=bTestc<e devient a\lebTestc\lte. Comment puis-je atteindre ce par programme? J'utilise un modèle Regex défini ci-dessous en concaténant tous les éléments de la première colonne du tableau dentelé, en utilisant le séparateur | (Regex "OR") entre chaque élément. J'ai concaténé les éléments en prenant les éléments de l'ordre de la plus grande longueur à la plus courte longueur de sorte que si l'élément plus court est contenu dans l'élément plus grand, il n'est pas remplacé [Ref: Example. J'utilise .NET 4.5.2Remplacer la première valeur de colonne par la deuxième valeur de colonne à l'aide de Regex dans le tableau dentelé

string[][] sSymb = { new string[] { "!=", "ne" }, new string[] { "lt=", "leq" }, new string[] { "<", "lt" }, new string[] { ">", "gt" }, new string[] { "<=", "le" }, new string[] { "gt=", "geq" }, new string[] { ">=", "ge" }, new string[] { "!in", "notin" }, new string[] { "sub", "subset" }, new string[] { "sup", "supset" } }; 
string sPattern = "gt=|!in|sub|sup|!=|<=|lt|>=|<|>"; 
Regex regex = new Regex(sPattern); 
string st = regex.Replace("a<=bcd<e", "\\$&"); //this prepends the first column element of array with \ . I need to replace the first column element with \ + second column element 
Console.WriteLine(st); 
+0

Salut! J'ai ajouté dans un exemple de comment réaliser ce que vous êtes après avoir utilisé le tableau en dents de scie; mais je pense que le dictionnaire ordonné est une solution plus élégante. J'espère que cela pourra aider! – gerrod

Répondre

1

La meilleure façon d'y parvenir serait d'utiliser le overload for replace which allows you to pass in a match evaluator.

string st = regex.Replace("a<=bcd<e", match => 
{ 
    var matchingSymbol = sSymb.FirstOrDefault(symbol => symbol[0] == match.Value); 
    if (matchingSymbol == null) 
     throw new Exception("Could not find symbol to exchange."); 

    return string.Concat("\\", matchingSymbol[1]); 
}); 

Également - devez-vous utiliser un tableau en dents de scie? Ce serait beaucoup plus facile d'utiliser un dictionnaire.

Édition: J'ai juste jeté un autre coup d'œil à vos clés pour vous rendre compte que l'ordre sera très important ici. Vous devez vous assurer que vos entrées à remplacer sont classées du plus spécifique au moins spécifique (sinon le moteur regex correspondra à "<" alors qu'il aurait pu correspondre à "< =").

Dans ce cas, un dictionnaire Ordonné serait probablement la meilleure façon d'y parvenir:

var sSymb = new System.Collections.Specialized.OrderedDictionary 
{ 
    { "<=", "le" }, 
    { ">=", "ge" }, 
    { "!=", "ne" }, 
    { "<", "lt" }, 
    { ">", "gt" }, 
    { "gt=", "geq" }, 
    { "lt=", "leq" }, 
    { "!in", "notin" }, 
    { "sub", "subset" }, 
    { "sup", "supset" } 
}; 

var sPattern = sSymb.Keys 
    .Cast<string>() 
    .Aggregate((left, right) => string.Format("{0}|{1}", left, right)); 

Regex regex = new Regex(sPattern); 
string st = regex.Replace("a<=bcd<e", match => string.Format("\\{0}", sSymb[match.Value])); 
Console.WriteLine(st); 
+0

Je suis d'accord que votre solution de dictionnaire ordonnée est une meilleure solution. Pour moi, la partie la plus importante de votre solution - «qui m'a le plus aidé» - était de savoir comment utiliser la valeur du dictionnaire basée sur la clé correspondante. L'ordre des éléments de collection dans vos deux solutions est important. Question: Dans mon cas, sortedList sera un meilleur choix que le dictionnaire ordonné? – nam

+0

Non, le dictionnaire ordonné est préférable car le temps de recherche des éléments est (généralement) plus rapide, car un dictionnaire utilise le hachage de l'objet pour récupérer ses éléments. – gerrod

+0

De plus, à moins d'implémenter un comparateur personnalisé, la liste triée ordonnera les éléments dans le mauvais ordre - '" <"' sera trié avant '" <= "'. Donc, si vous utilisez la liste triée pour construire votre motif regex automatiquement, il ne trouvera jamais des instances de '" <= "' (même chose pour '"> "' '' '' ''>> = '') – gerrod