Функция замены строки с поддержкой пользовательских подстановочных знаков и экранированием этих подстановочных знаков в C # - PullRequest
1 голос
/ 06 марта 2012

Мне нужно написать функцию замены строки с поддержкой пользовательских подстановочных знаков. Я также должен быть в состоянии избежать этих символов. В настоящее время у меня есть подстановочный класс со свойствами Usage, Value и Escape.

Допустим, у меня есть глобальный список с именем Wildcards . В Wildcards добавлен только один участник:

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

Так что мне нужен метод CustomReplace, чтобы сделать трюк. Я должен заменить указанный параметр в данной строке другой, такой же как string.Replace. Единственная разница здесь в том, что он должен использовать мои пользовательские шаблоны.

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?"

Мой текущий метод не поддерживает escape-строки. Это также не может быть хорошим, когда дело доходит до производительности, так как я вызываю строку. Замените два раза, и каждый из них ищет всю строку, я думаю.

// 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;
}

Итак, мне нужно написать метод замены, который ищет строку char по char с логикой, чтобы найти и разделить значения Usage и Escape, а затем заменить Escape на Usage при замене Usage другой данной строкой?

Или вы знаете уже написанное?

Могу ли я использовать регулярные выражения в этом scenerio?

Если я могу, то как? (Не имею опыта в этом, шаблон был бы неплох)

Если я это сделаю, будет ли он быстрее или медленнее, чем char при поиске символов?

Извините за длинный пост, я постарался сделать его понятным и извините за любые опечатки и тому подобное; это не мой основной язык. Заранее спасибо.

Ответы [ 4 ]

1 голос
/ 06 марта 2012

Вы можете попробовать это:

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;
}

Я думаю, что это самое простое и быстрое решение, поскольку существует только один Replace вызов метода для всех подстановочных знаков.

1 голос
/ 06 марта 2012

Почему вы не используете регулярные выражения INSTEAD ваших подстановочных знаков?

Готово:)

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

1 голос
/ 06 марта 2012

Так что, если вы счастливы просто использовать Regex для удовлетворения своих потребностей, вам следует проверить эту ссылку . У него есть отличная информация для использования в .Net. На сайте также есть множество примеров того, как создавать шаблоны Regex для самых разных нужд.

Базовый пример замены строки с символами подстановки может выглядеть следующим образом ...

string input = "my first regex replace";

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

//result is now "my first regex result"

обратите внимание, как второй аргумент в функции Replace принимает строку шаблона регулярного выражения. В этом случае точки действуют как символы подстановки, они в основном означают «соответствовать любому отдельному символу»

Надеюсь, это поможет вам получить то, что вам нужно.

0 голосов
/ 06 марта 2012

Если вы определили шаблон для своего подстановочного знака и метода escape, вы можете создать регулярное выражение, которое найдет все подстановочные знаки в вашем тексте. Затем вы можете использовать MatchEvaluator для их замены.

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;
        }
    }
}
...