Добавление всех экземпляров строки с символом - PullRequest
2 голосов
/ 22 декабря 2011

Я использую C #.NET 2.0 и WinForms.

У меня есть фрагмент кода, который отформатирован в ассемблере так:

VARIABLE = 40
ADDRESS = $60

LDA VARIABLE;
STA ADDRESS;

Вывод должен быть:

!VARIABLE = 40
!ADDRESS = $60

LDA !VARIABLE;
STA !ADDRESS;

Конечно,есть гораздо больше, чем это.Как 2000 строк, но дело в том, что в начале файла есть объявления, и я могу загружать / сохранять или делать с ними что угодно.Но моя проблема в том, что я должен «предварять» ВСЕ эти объявления (даже в необработанном коде) с помощью!.

Мой текущий метод такой:

        var defs = tab.tb.GetRanges(@"^\s*([A-Za-z0-9_]+){4,255}\s*=", RegexOptions.Multiline); // all declarations are formatted like this, so use regex to get all of them
        foreach (var def in defs)
        {
            string actual = def.Text.Substring(0, def.Text.IndexOf(' ')); // remove the = sign since its not used in actual code
                txt = txt.Replace(actual, "!" + actual);
        }

Однако этот методочень медленноТребуется приблизительно 3 секунды, чтобы "исправить" все объявления в моем файле.Есть ли лучший способ?И для записи, синтаксис немного отличается от обычного текстового поля, потому что я использую http://www.codeproject.com/KB/edit/FastColoredTextBox_.aspx в качестве текстового элемента управления.

Ответы [ 3 ]

2 голосов
/ 22 декабря 2011

Вот быстрая попытка. На моей машине это обрабатывает файл с 25 000 строк в <100 мс. </p>

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

Обновление: я попробовал другой пример, на этот раз с 25000 строками и 8 уникальными значениями для изменения. Производительность снижается только на несколько миллисекунд.

Stopwatch sw = new Stopwatch();
string text = File.ReadAllText( @"C:\\temp\so.txt" );

sw.Start();

// find the tokens we will be replacing
Regex tokenFinder = new Regex( @"^(([A-Za-z0-9_]+){4,255})\s*(=)", RegexOptions.Multiline );

// ensure uniqueness, and remove "=" by looking at the second match group
var tokens = ( from Match m in tokenFinder.Matches( text ) select m.Groups[1].Value ).Distinct();

// perform replace for each token...performance here will greatly vary based on the number of tokens to replace
foreach( string token in tokens )
{
    Regex replaceRegex = new Regex( token );
    text = replaceRegex.Replace( text, string.Concat( "!", token.Trim() ) );
}

sw.Stop();
Console.WriteLine( "Complete in {0}ms.", sw.ElapsedMilliseconds );
2 голосов
/ 22 декабря 2011

Я подозреваю, что ваша проблема с производительностью заключается в замене str. Строки в .NET являются неизменяемыми, поэтому при выполнении любой операции, которая изменяет строку (добавление, замена и т. Д.), .NET должна создать новую строку и скопировать в нее старую (все 2000 строк) плюс перемены. Попробуйте вместо этого загрузить строку в StringBuilder (который является изменяемым) и использовать его собственный метод .Replace ().

1 голос
/ 22 декабря 2011

Вы вкладываете квантификаторы в свое регулярное выражение!

([A-Za-z0-9_]+){4,255}

Возьмите простую строку как 'aaaaaaaa': что должен захватывать механизм регулярных выражений?'a' 8 раз, 'aa' 4 раза, 'aa', затем 'a', затем 'a', затем ...?

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

Удалите +!

...