Я должен сделать 2 правила "замена" - мои правила, заменяют, все открывают parens, "(" с дефисом "-" и разделяют все закрытие parens")".
Так, например, это:
"foobar (baz2)" стал бы
"foobar-baz2"
Я в настоящее время делаю это как это - но, моя догадка regex была бы более чистой.
myString.Replace("(", "-").Replace(")", "");
Я бы не стал использовать RegEx для этого - то, что вы делаете, правильно. Это ясно и просто ... регулярные выражения вряд ли сделают это проще или понятнее. Вам все равно нужно будет сделать два вызова Replace
, потому что ваши замены различны для каждого случая.
Нет. Это совершенно чисто.
Дело в том, что вам все равно придется иметь два регулярных выражения, потому что ваши строки подстановки разные.
Регулярное выражение является излишним для такого простого сценария. То, что у вас есть, идеально. Хотя на ваш вопрос уже был дан ответ, я хотел опубликовать сообщение, чтобы продемонстрировать, что одного шаблона регулярного выражения достаточно:
string input = "foobar(baz2)";
string pattern = "([()])";
string result = Regex.Replace(input, pattern, m => m.Value == "(" ? "-" : "");
Console.WriteLine(result);
Идея состоит в том, чтобы зафиксировать круглые скобки в группе. Я использовал [()]
, который представляет собой класс символов, который будет соответствовать тому, что нам нужно. Обратите внимание, что внутри класса символов их не нужно экранировать. В качестве альтернативы шаблон мог быть @ "(\ (| \))"
, и в этом случае необходимо экранирование.
Затем метод Replace
использует MatchEvaluator, и мы проверяем, является ли полученное значение открытием (
или нет. Если это так, то используется -
Если нет, мы знаем, исходя из нашего ограниченного шаблона, что это должно быть закрытие )
, и мы возвращаем пустую строку.
Я бы сказал, используйте то, что у вас есть - это легче читать / поддерживать. Регулярные выражения очень мощные, но иногда и очень запутанные. Для чего-то такого простого, я бы сказал, даже не используйте регулярные выражения.
Мне внезапно приходит в голову Джейми Завински:
Некоторые люди, сталкиваясь с проблемой, думают: «Я знаю, я буду использовать регулярные выражения. " Теперь у них две проблемы.
Так что я тоже считаю, что Л.Бушкин прав в этом случае. Ваше решение работает и доступно для чтения.
Вот забавное решение проблемы на основе LINQ. Возможно, это не лучший вариант, но в любом случае он интересен:
public string SearchAndReplace(string input)
{
var openParen = '(';
var closeParen = ')';
var hyphen = '-';
var newChars = input
.Where(c => c != closeParen)
.Select(c => c == openParen ? hyphen : c);
return new string(newChars.ToArray());
}
2 интересных замечания об этой реализации:
Неплохо!
Вы можете использовать один regex для замены обоих этих вхождений в одной строке, но это будет менее "щадящим", чем две замены строки с одним правилом.
Пример:
Код, который можно использовать для того, чтобы сделать то, что вы хотите с помощью regex, будет таким:
Regex.Replace(myString, @"([^\(]*?)\(([^\)]*?)\)", "$1-$2");
Это будет отлично работать именно для того примера, который вы привели. Если бы было хоть малейшее изменение в том, где и сколько символов '(' и ')', регекс бы сломался. Вы могли бы исправить это с помощью еще одного регекса, но дальше все становилось бы только уродливее и уродливее.
Однако регекс - отличный выбор для более жестких приложений.
Я бы подумал, что регулярное выражение будет хрупким для такого рода вещей. Если в вашей версии .NET есть методы расширения и вам нужен более чистый синтаксис, который масштабируется, вы можете ввести такой метод расширения:
public static class StringExtensions
{
public static string ReplaceMany(this string s, Dictionary<string, string> replacements)
{
var sb = new StringBuilder(s);
foreach (var replacement in replacements)
{
sb = sb.Replace(replacement.Key, replacement.Value);
}
return sb.ToString();
}
}
Итак, теперь вы создаете свой словарь замен ...
var replacements = new Dictionary<string, string> { {"(", "-"}, {")", ""} };
И вызываете ReplaceMany:
var result = "foobar(baz2)".ReplaceMany(replacements); // result = foobar-baz2
Если вы действительно хотите продемонстрировать свое намерение, вы можете использовать псевдоним Dictionary
до StringReplacements
:
//At the top
using StringReplacements = System.Collections.Generic.Dictionary<string,string>;
//In your function
var replacements = new StringReplacements() { {"(", "-"}, {")", ""} };
var result = "foobar(baz2)".ReplaceMany(replacements);
Может быть, только две замены будут излишними, но если у вас есть многие из них будут чище, чем .Replace (). Replace (). Replace (). Replace () ...
.