2013-01-23 11 views
5

に2枚のセパレータの間にサブストリングを取得:Iは、文字列以下た任意の位置

string source = "Test/Company/Business/Department/Logs.tvs/v1"; 

/文字が文字列内の様々な要素間のセパレータです。私は文字列の最後の2つの要素を取得する必要があります。私はこの目的のために次のコードを持っています。これは正常に動作します。これにはより高速で簡単なコードがありますか?

CODE

static void Main() 
    { 
     string component = String.Empty; 
     string version = String.Empty; 
     string source = "Test/Company/Business/Department/Logs.tvs/v1"; 
     if (!String.IsNullOrEmpty(source)) 
     { 
      String[] partsOfSource = source.Split('/'); 
      if (partsOfSource != null) 
      { 
       if (partsOfSource.Length > 2) 
       { 
        component = partsOfSource[partsOfSource.Length - 2]; 
       } 

       if (partsOfSource.Length > 1) 
       { 
        version = partsOfSource[partsOfSource.Length - 1]; 
       } 
      } 
     } 

     Console.WriteLine(component); 
     Console.WriteLine(version); 
     Console.Read(); 
    } 

答えて

4

なぜ正規表現はありませんか?この1はかなり簡単です:

component = myMatch.Groups["component"]; 
version = myMatch.Groups["version"]; 
+1

をこのような場合に正規表現エンジンが「右から」一致するようにしないでください。 – Rawling

+1

@ Rawling:同意。私はあなたが文字列を最初に逆にすることができると思うが、それはおそらく効率がさらに低い。実際には、式に '$'はあるが '^'はないときにRegExエンジンがその種の最適化を組み込むことはできないのだろうかと思う。 –

+2

... OK、今日は、 'Regex.Match(source、" /(.*?)$ "、RegexOptions.RightToLeft)'や '$'この場合。 – Rawling

2

あなたのコードはほとんどが正常に見えます。注目すべき点のいくつか:

  1. はnullを返さないので、ヌルチェックは必要ありません。
  2. source文字列の文字数が2文字未満の場合は、どうすれば対処できますか?
  3. ソース文字列がヌルまたは空(または無効)の場合は、空の文字列を実際に出力したいですか?入力の性質について具体的な期待がある場合は、それらの期待が満たされていない場合には失敗を早めることを検討することができます。
2

あなたのアプローチは、あなたが探していることを考えると、最も適切なものである:あなたの試合のためにすべてを行う必要があるので、

.*/(?<component>.*)/(?<version>.*)$ 

あなたも、あなたのグループにラベルを付けることができます特定のインデックスの部分文字列。この場合に同じことを行うLINQ式は、コードやその可読性を改善しない可能性があります。

参考までに、Microsoft hereには、文字列とLINQの使用に関する素晴らしい情報があります。特に、hereの記事でLINQとRegExの両方の例を扱っています。

EDIT:+1 RegExアプローチ内のMattの名前付きグループについて...これは私が見た最も良い解決策です。

3

それは2 /を見つけるためにする必要として、それは文字列のみの限りスキャンし、それが文字列全体分割されるのを気にしないよう、速くする必要があります:

string component = ""; 
string version = ""; 
string source = "Test/Company/Business/Department/Logs.tvs/v1"; 
int last = source.LastIndexOf('/'); 
if (last != -1) 
{ 
    int penultimate = source.LastIndexOf('/', last - 1); 
    version = source.Substring(last + 1); 
    component = source.Substring(penultimate + 1, last - penultimate - 1); 
} 

言いましたすべてのパフォーマンスに関する質問と同様に、プロファイル! 2人を実際の入力の大きなリストで並べてみて、どちらが最速かを見てみましょう。

sourceがnullの場合にも、これは怠惰な、私は空の文字列を残すのではなく、入力にはスラッシュがない場合は例外をスロー...しかし、スローされます。)

+0

これは早すぎる最適化のようです。この文字列を分割すると、パフォーマンスのボトルネックになる可能性は非常に低いです。 – StriplingWarrior

+0

まだ、OPがより速く/簡単なコードを要求したとき... – Rawling

1

あなたが好きなものを試みることができますこれははるかに速くなるとは思っていません。 System.Diagnostics.StopWatchを使用して、必要があると感じるかどうか確認することができます。

string source = "Test/Company/Business/Department/Logs.tvs/v1"; 

int index1 = source.LastIndexOf('/'); 
string last = source.Substring(index1 + 1); 

string substring = source.Substring(0, index1); 
int index2 = substring.LastIndexOf('/'); 
string secondLast = substring.Substring(index2 + 1); 
1

私は、これはあなたが以下のようにプロセスを使用して、最後の二つの単語検索することができ

+0

面白い...ありがとう – Lijo

+1

@LijoはR#からいくつかのリファクタリングで私の答えを編集し、components.Count <2をサポートしました – jbl

-1

を助ける

 string source = "Test/Company/Business/Department/Logs.tvs/v1"; 

     var components = source.Split('/').Reverse().Take(2); 

     String last = string.Empty; 

     var enumerable = components as string[] ?? components.ToArray(); 
     if (enumerable.Count() == 2) 
      last = enumerable.FirstOrDefault(); 
     var secondLast = enumerable.LastOrDefault(); 

希望しようとするだろう:それはあなたができる恥だ

string source = "Test/Company/Business/Department/Logs.tvs/v1"; 

String[] partsOfSource = source.Split('/'); 
if(partsOfSourch.length>2) 
for(int i=partsOfSourch.length-2;i<=partsOfSource.length-1;i++) 
console.writeline(partsOfSource[i]); 
関連する問題