A string replace function with support of custom w

2019-06-04 03:27发布

问题:

I need to write a string replace function with custom wildcards support. I also should be able to escape these wildcards. I currently have a wildcard class with Usage, Value and Escape properties.

So let's say I have a global list called Wildcards. Wildcards has only one member added here:

Wildcards.Add(new Wildcard
{
    Usage = @"\Break",
    Value = Enviorement.NewLine,
    Escape = @"\\Break"
});

So I need a CustomReplace method to do the trick. I should replace the specified parameter in a given string with another one just like the string.Replace. The only difference here that it must use my custom wildcards.

string test = CustomReplace("Hi there! What's up?", "! ", "!\\Break");
// Value of the test variable should be: "Hi there!\r\nWhat's up?"
// Because \Break is specified in a custom wildcard in Wildcards

// But if I use the value of the wildcard's Escape member,
// it should be replaced with the value of Usage member.
test = CustomReplace("Hi there! What's up?", "! ", "!\\\\Break");
// Value of the test variable should be: "Hi there!\\BreakWhat's up?"

My current method doesn't support escape strings. It also can't be good when it comes to performance since I call string.Replace two times and each one searches the whole string, I guess.

// My current method. Has no support for escape strings.
CustomReplace(string text, string oldValue, string newValue)
{
    string done = text.Replace(oldValue, newValue);
    foreach (Wildcard wildcard in Wildcards)
    {
        // Doing this:
        // done = done.Replace(wildcard.Escape, wildcard.Usage);
        // ...would cause trouble when Escape contains Usage.

        done = done.Replace(wildcard.Usage, wildcard.Value);
    }

    return done;
}

So, do I have to write a replace method which searches the string char by char with the logic to find and seperate both Usage and Escape values, then replace Escape with Usage while replacing Usage with another given string?

Or do you know an already written one?

Can I use regular expressions in this scenerio?

If I can, how? (Have no experience in this, a pattern would be nice)

If I do, would it be faster or slower than char by char searching?

Sorry for the long post, I tried to keep it clear and sorry for any typos and such; it's not my primary language. Thanks in advance.

回答1:

You can try this:

public string CustomReplace(string text, string oldValue, string newValue)
{
    string done = text.Replace(oldValue, newValue);

    var builder = new StringBuilder();
    foreach (var wildcard in Wildcards)
    {
        builder.AppendFormat("({0}|{1})|", Regex.Escape(wildcard.Usage),
            Regex.Escape(wildcard.Escape));
    }
    builder.Length = builder.Length - 1; // Remove the last '|' character

    return Regex.Replace(done, builder.ToString(), WildcardEvaluator);
}

private string WildcardEvaluator(Match match)
{
    var wildcard = Wildcards.Find(w => w.Usage == match.Value);

    if (wildcard != null)
        return wildcard.Value;
    else
        return match.Value;
}

I think this is the easiest and fastest solution as there is only one Replace method call for all wildcards.



回答2:

So if you are happy to just use Regex to fulfil your needs then you should check out this link. It has some great info for using in .Net. The website also has loads of examples on who to construct Regex patterns for many different needs.

A basic example of a Replace on a string with wildcards might look like this...

string input = "my first regex replace";

string result = System.Text.RegularExpressions.Regex.Replace(input, "rep...e", "result");

//result is now "my first regex result"

notice how the second argument in the Replace function takes a regex pattern string. In this case, the dots are acting as a wildcard character, they basically mean "match any single character"

Hopefully this will help you get what you need.



回答3:

Why dont you use the regular expressions INSTEAD of your wildcards?

It's ready made :)

http://www.radsoftware.com.au/articles/regexlearnsyntax.aspx

http://www.c-sharpcorner.com/UploadFile/prasad_1/RegExpPSD12062005021717AM/RegExpPSD.aspx

http://msdn.microsoft.com/en-us/library/ms228595(v=vs.80).aspx



回答4:

If you define a pattern for both your wildcard and your escape method, you can create a Regex which will find all the wildcards in your text. You can then use a MatchEvaluator to replace them.

class Program
{
    static Dictionary<string, string> replacements = new Dictionary<string, string>();

    static void Main(string[] args)
    {
        replacements.Add("\\Break", Environment.NewLine);

        string template = @"This is an \\Break escaped newline and this should \Break contain a newline.";

        // (?<=($|[^\\])(\\\\){0,}) will handle double escaped items
        string outcome = Regex.Replace(template, @"(?<=($|[^\\])(\\\\){0,})\\\w+\b", ReplaceMethod);

    }

    public static string ReplaceMethod(Match m)
    {
        string replacement = null;
        if (replacements.TryGetValue(m.Value, out replacement))
        {
            return replacement;
        }
        else
        {
            //return string.Empty?
            //throw new FormatException()?
            return m.Value;
        }
    }
}