41 votes

Comment ignorer la casse en Chaîne.remplacer

string sentence = "We know it contains 'camel' word.";
// Camel can be in different cases:
string s1 = "CAMEL";
string s2 = "CaMEL";
string s3 = "CAMeL";
// ...
string s4 = "Camel";
// ...
string s5 = "camel";

Comment remplacer 'chameau' dans la phrase avec "cheval" en dépit de l' string.Replace ne prend pas en charge ignoreCase sur la chaîne de gauche?

56voto

tvanfosson Points 268301

Utiliser une expression régulière:

var regex = new Regex( "camel", RegexOptions.IgnoreCase );
var newSentence = regex.Replace( sentence, "horse" );

Bien sûr, cela permettra également à associer des mots contenant le chameau, mais il n'est pas clair si vous le voulez ou pas.

Si vous avez besoin de correspondances exactes que vous pouvez utiliser une coutume MatchEvaluator.

public static class Evaluators
{
    public static string Wrap( Match m, string original, string format )
    {
        // doesn't match the entire string, otherwise it is a match
        if (m.Length != original.Length)
        {
            // has a preceding letter or digit (i.e., not a real match).
            if (m.Index != 0 && char.IsLetterOrDigit( original[m.Index - 1] ))
            {
                return m.Value;
            }
            // has a trailing letter or digit (i.e., not a real match).
            if (m.Index + m.Length != original.Length && char.IsLetterOrDigit( original[m.Index + m.Length] ))
            {
                return m.Value;
            }
        }
        // it is a match, apply the format
        return string.Format( format, m.Value );
    }
} 

Utilisé avec l'exemple précédent pour envelopper le match dans une durée de:

var regex = new Regex( highlightedWord, RegexOptions.IgnoreCase );
foreach (var sentence in sentences)
{
    var evaluator = new MatchEvaluator( match => Evaluators.Wrap( match, sentence, "<span class='red'>{0}</span>" ) );
    Console.WriteLine( regex.Replace( sentence, evaluator ) );
}

25voto

Tom Beech Points 666

Ajouter une méthode d'extension de chaîne pour faire l'affaire:

Utilisation:

string yourString = "TEXTTOREPLACE";
yourString.Replace("texttoreplace", "Look, I Got Replaced!", StringComparison.OrdinalIgnoreCase);

Code:

using System;
using System.Collections.Generic;
using System.IO;

public static class Extensions
{
    public static string Replace(this string source, string oldString, string newString, StringComparison comp)
    {
        int index = source.IndexOf(oldString, comp);

        // Determine if we found a match
        bool MatchFound = index >= 0;

        if (MatchFound)
        {
            // Remove the old text
            source = source.Remove(index, oldString.Length);

            // Add the replacemenet text
            source = source.Insert(index, newString);            
        }

        return source;
    }
}

12voto

johv Points 1108

Voici une méthode d'extension de prendre un StringComparison, l'aide de la chaîne.IndexOf:

    [Pure]
    public static string Replace(this string source, string oldValue, string newValue, StringComparison comparisonType)
    {
        if (source.Length == 0 || oldValue.Length == 0)
            return source;

        var result = new System.Text.StringBuilder();
        int startingPos = 0;
        int nextMatch;
        while ((nextMatch = source.IndexOf(oldValue, startingPos, comparisonType)) > -1)
        {
            result.Append(source, startingPos, nextMatch - startingPos);
            result.Append(newValue);
            startingPos = nextMatch + oldValue.Length;
        }
        result.Append(source, startingPos, source.Length - startingPos);

        return result.ToString();
    }

Btw, voici également une semblable Contient-méthode, en outre, un StringComparison:

    [Pure]
    public static bool Contains(this string source, string value, StringComparison comparisonType)
    {
        return source.IndexOf(value, comparisonType) >= 0;
    }

Quelques tests:

[TestFixture]
public class ExternalTests
{
    private static string[] TestReplace_args =
        {
            "ab/B/c/ac",
            "HELLO World/Hello/Goodbye/Goodbye World",
            "Hello World/world/there!/Hello there!",
            "hello WoRlD/world/there!/hello there!",
            "///",
            "ab///ab",
            "/ab/cd/",
            "a|b|c|d|e|f/|//abcdef",
            "a|b|c|d|e|f|/|/:/a:b:c:d:e:f:",
        };

    [Test, TestCaseSource("TestReplace_args")]
    public void TestReplace(string teststring)
    {
        var split = teststring.Split("/");
        var source = split[0];
        var oldValue = split[1];
        var newValue = split[2];
        var result = split[3];
        Assert.That(source.Replace(oldValue, newValue, StringComparison.OrdinalIgnoreCase), Is.EqualTo(result));
    }
}

3voto

whiteshooz Points 51

Utiltize StringComparison , en raison de sa pratique OrdinalIgnoreCase

    string sentence = "We know it contains 'camel' word."; 
    string wordToFind = "camel";
    string replacementWord = "horse";

    int index = sentence.IndexOf(wordToFind , StringComparison.OrdinalIgnoreCase)
    // Did we match the word regardless of case
    bool match = index >= 0;

    // perform the replace on the matched word
    if(match) {
        sentence = sentence.Remove(index, wordToFind.Length)
        sentence = sentence.Insert(index, replacementWord)
    }

Ça serait bien si le C# String classe avait un ignoreCase() méthode comme Java.

2voto

Quanta Points 295

Vous pouvez également utiliser des chaînes de caractères.IndexOf

http://msdn.microsoft.com/en-us/library/system.string.indexof.aspx

Vous pouvez obtenir des performances légèrement meilleures de le faire de cette façon qu'avec RegExpressions (j'ai horreur d'eux parce qu'ils ne sont pas intuitives et faciles à visser, même si cette simple .Net appel de fonction abstraction du réel désordre RegEx, et ne fournit pas beaucoup de place pour l'erreur), mais ce n'est probablement pas une préoccupation pour vous, les ordinateurs sont très vite ces jours-ci, à droite? :) La surcharge pour IndexOf qui prend un StringComparison objet, vous pouvez éventuellement ignorer la casse, et parce que IndexOf renvoie la première occurrence de à une position donnée, vous devrez le code d'une boucle pour traiter une chaîne de multiples occurrences.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X