SORU
18 Kasım 2008, Salı


Dize dize içine komut satırı parametreleri içeren[] Split C#

Ben tek bir dize içeren bir komut satırı parametreleri iletilmesi için başka bir yürütülebilir ve gerek özü, string [], içeren bireysel parametreleri aynı şekilde C# olsaydı komutları gördüğü belirtilen komut satırı. String[] bir başka derlemeler yansıması. üzerinden noktadan giriş yürütürken kullanılacak

Bunun için standart bir işlevi var mı? Yoksa tercih edilen bir yöntem (düzenli ifade?) bölme parametrelerini doğru? İşlemek gerekir"' sadece bölme yapamam yani boşluk doğru içerme ihtimali olan dizelerini ayrılmış'.''

Örnek dize:

string parameterString = @"/src:""C:\tmp\Some Folder\Sub Folder"" /users:""abcdefg@hijkl.com"" tasks:""SomeTask,Some Other Task"" -someParam foo";

Örnek sonuç:

string[] parameterArray = new string[] { 
  @"/src:C:\tmp\Some Folder\Sub Folder",
  @"/users:abcdefg@hijkl.com",
  @"tasks:SomeTask,Some Other Task",
  @"-someParam",
  @"foo"
};

Komut satırı ayrıştırma kütüphane, bir şekilde Dize almaya ihtiyacım yok[] olarak oluşturulmuş olmalıdır.

GüncellemeAslında C tarafından oluşturulan eşleşmesi için beklenen sonucu değiştirmek zorunda kaldım# (ekstra kaldırıldı "'split' In dizeleri)

CEVAP
18 Kasım 2008, Salı


Bir dize her karakter inceleyen bir işlevi dayalı split fonksiyonu yok Hayır bu beni rahatsız ediyor. Eğer olsaydı, bu gibi yazabilirsiniz:

    public static IEnumerable<string> SplitCommandLine(string commandLine)
    {
        bool inQuotes = false;

        return commandLine.Split(c =>
                                 {
                                     if (c == '\"')
                                         inQuotes = !inQuotes;

                                     return !inQuotes && c == ' ';
                                 })
                          .Select(arg => arg.Trim().TrimMatchingQuotes('\"'))
                          .Where(arg => !string.IsNullOrEmpty(arg));
    }

Bu yazılı olmasına rağmen, neden gerekli uzatma yöntemleri yazmak değil. Tamam, beni ikna ettin...

Öncelikle, belirtilen karakter ayrılmaması gerektiğine karar vermek için bir işlev alır Bölünmüş benim kendi versiyonunu dize:

    public static IEnumerable<string> Split(this string str, 
                                            Func<char, bool> controller)
    {
        int nextPiece = 0;

        for (int c = 0; c < str.Length; c  )
        {
            if (controller(str[c]))
            {
                yield return str.Substring(nextPiece, c - nextPiece);
                nextPiece = c   1;
            }
        }

        yield return str.Substring(nextPiece);
    }

Bazı boş dizeler duruma bağlı olarak verim olabilir, ama belki bu bilgi bu işlev, boş girdileri kaldırmak istemiyorum bu yüzden diğer durumlarda yararlı olacaktır.

Bir dize başlangıç ve bitiş tırnak eşleşen bir çift süs olacak küçük bir yardımcı ikincisi (ve daha mundanely). Standart Döşeme yöntemi - sadece her ucundan bir karakter trim, ve sadece bir ucundan döşeme değil daha titiz

    public static string TrimMatchingQuotes(this string input, char quote)
    {
        if ((input.Length >= 2) && 
            (input[0] == quote) && (input[input.Length - 1] == quote))
            return input.Substring(1, input.Length - 2);

        return input;
    }

Ve bazı testler de istersiniz sanırım. İyi, Tamam o zaman. Ama bu son şey, kesinlikle olmalı! Beklenen dizi ile bölme sonucu karşılaştıran ilk yardımcı fonksiyon içeriği:

    public static void Test(string cmdLine, params string[] args)
    {
        string[] split = SplitCommandLine(cmdLine).ToArray();

        Debug.Assert(split.Length == args.Length);

        for (int n = 0; n < split.Length; n  )
            Debug.Assert(split[n] == args[n]);
    }

O zaman bu gibi testleri yazabilirim:

        Test("");
        Test("a", "a");
        Test(" abc ", "abc");
        Test("a b ", "a", "b");
        Test("a b \"c d\"", "a", "b", "c d");

İşte ihtiyaçlarınız için test:

        Test(@"/src:""C:\tmp\Some Folder\Sub Folder"" /users:""abcdefg@hijkl.com"" tasks:""SomeTask,Some Other Task"" -someParam",
             @"/src:""C:\tmp\Some Folder\Sub Folder""", @"/users:""abcdefg@hijkl.com""", @"tasks:""SomeTask,Some Other Task""", @"-someParam");

Uygulama mantıklı (TrimMatchingQuotes işlevi sayesinde) bir bağımsız değişken tırnak kaldıracak ekstra özelliği olduğunu unutmayın. Bu komut satırı yorumu normal bir parçası olduğuna inanıyorum.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • backyardjay

    backyardjay

    8 ŞUBAT 2009
  • SunsetTrance

    SunsetTrance

    20 EYLÜL 2008
  • sWooZie

    sWooZie

    9 ŞUBAT 2006