Что делает C # /. NET 2.0 RegEx.Replace, если ничего не нужно заменить - PullRequest
1 голос
/ 04 ноября 2010

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

public static void ReplaceOldWithNew(ref string input)
{
    string pattern = //something here
    input = Regex.Replace(input, pattern, FormatReplacement);
}

private string FormatReplacement(Match m)
{
    return String.Concat("x", formatCount++);
}

если у меня это так

public static void ReplaceOldWithNew(ref string input)
{
    string pattern = //something here
    if (RegEx.IsMatch(input, pattern))
       input = Regex.Replace(input, pattern, FormatReplacement);
}

проблема в том, что он ищет входную строку два раза, если есть совпадение (я).Есть ли решение, которое будет искать совпадения только один раз и создавать новый экземпляр строки только при необходимости.Может быть, используя RegEx.Matches или что-то.

Спасибо & BR - Matti

Ответы [ 2 ]

3 голосов
/ 04 ноября 2010

Если вы проверяете Regex.Replace с помощью Reflector , это в конечном итоге делает это внутренне:

Match match = regex.Match(input, startat);
if (!match.Success)
{
    return input;
}

Другими словами, если шаблон не совпадает, он рано выходит и возвращаеторигинальный ввод.Ваше использование Regex.IsMatch выполняет двойную работу, но это единственный способ заранее узнать, существует ли совпадение, поскольку Regex.Replace возвращает строку без указания того, существовало ли совпадение для начала.Использование Match с циклом или Matches не поможет вам восстановить исходную строку, поскольку вам нужно будет выяснить индексы соответствия (используйте свойство Index в Match) и разбить его на части.все вместе.

Если вы планируете использовать регулярное выражение много, вы можете использовать опцию RegexOptions.Compiled.Объявите свой объект Regex и используйте его во всем коде.Вам нужно будет провести некоторое исследование по этому вопросу и оценить, стоит ли оно того (т. Е. Везде использовать эту опцию для сценариев, в которых она не нужна).

0 голосов
/ 04 ноября 2010

Краткий ответ: создайте объект Regex, а затем, когда вы выполните поиск, у вас будет коллекция совпадений, которую вы можете вызвать заменить. Примерно так:

var regex = new Regex(pattern, RegexOptions.Compiled);
foreach (var currentMatch in regex.Matches)
{
    //Do stuff
}

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

...