2011-12-22 10 views
2

私はC#を使用しています。 NET 2.0およびWinForms。文字列のすべてのインスタンスを先頭にchar

私はこのようなアセンブリでフォーマットされたコードの部分を持っている:

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を使用しているため、レコードのために、構文は通常のテキストボックスと少し異なります。

+0

この例では、 'VARIABLE'と' ADDRESS'(行1と2)の前に '!'を付けますが、残りの部分は入れませんか?あるいは、各行の前に4つの '! 'があるでしょうか?サンプルの出力は少しわかります – Prescott

+0

部分文字列ではなく正規表現置換()を使用して新しい文字列を再割り当てすることがより速くなるかもしれません:http://msdn.microsoft.com/en-us/ /library/system.text.regularexpressions.regex.replace.aspx –

+0

@TimMedoraしかし、正規表現マッチの部分文字列をどうやって取得できますか?私の正規表現は "VARIABLE ="を返し、 "VARIABLE"のすべてのインスタンスを置き換える必要があります。 – david

答えて

1

正規表現に数量子を入れ子にします。

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

「aaaaaaaa」という単純な文字列を使用します。キャプチャするはずの正規表現エンジンは何ですか? 'a' 8回、 'aa' 4回、 'aa'、 'a'、 'a'、そして...?

これはおそらく、パフォーマンス上の問題の原因です。ちょうどそれをしないでください!すべてファイル内で一致するようにしてください。正規表現エンジンは最終的に最長最長一致を選択しますが、常にすべての可能性を試しています。

+を削除してください!

+0

{4,255}については、実際には{4、}にする必要がありますが、パフォーマンスは向上しません。あなたの方法が違っていない限り、これはまさに私がやっていることです。 – david

+0

コミット編集を参照してください。実際には、あなたのinital正規表現から '+'を削除するだけで、おそらく処理が速くなります。 – fge

+0

あなたはそうです!私が+を削除したとき、物事はより早く進むように見えました。それを考えると、なぜ私が最初にそれを追加したのかわからない。 – david

2

あなたのパフォーマンス上の問題はstrの交換を行うことにあると思われます。 .NETの文字列は不変なので、文字列を変更する操作(追加、置換など)を行う場合、.NETは新しい文字列を作成して古い文字列をその中にコピーします(2000行すべて)。変更。文字列をStringBuilder(変更可能)に読み込み、そのネイティブの.Replace()メソッドを使用してみてください。

+0

それは0.1秒で速度が向上するようですが、これはかなり良いでしょう。それを指摘してくれてありがとう。 – david

2

ここはすばやい試みです。私のマシンでは、これは< 100msの25000 +ラインファイルを処理します。

しかし、私はこれをオフにするための2つのサンプル値しか持っていません。より多くの置換操作でパフォーマンスが低下します。

更新:もう1つのサンプルを試しましたが、今回は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); 
+0

Linqを使用しています。私はNET 2.0を使用しています。 :Pただし、このファイルを同じファイルでテストしたところ、パフォーマンスは(わずかな量で)遅くなりました。 – david

+0

@david - サンプルデータを投稿する可能性はありますか?私は不一致について不思議です。 –

関連する問題