2009-04-07 18 views
5

C#, NET 3.5C# içinde bir dizgiyi ayrıştırma; daha temiz bir yol var mı?

Bu sadece bana çirkin kokuyor, ama başka bir şekilde düşünemiyorum.

"Joe Smith (jsmith)" (sans quotes) biçimindeki bir dize verildiğinde, yalnızca parantez içindeki "jsmith" dizesini ayrıştırmak istiyorum. RegEx'in benim (me) sağlıklı kaçınma daha

private static string DecipherUserName(string user) 
{ 
    if(!user.Contains("(")) 
     return user; 

    int start = user.IndexOf("("); 

    return user.Substring(start).Replace("(", string.Empty).Replace(")", string.Empty); 
} 

Diğer, alt dizeyi ayrıştırmak için daha basit bir yolu var

: Ben bu ile geldim?

Düzenleme: "Joe Smith (gozdemir)" (sans tırnak): dize her zaman olacaktır ayrıştırmak için, netleştirmek için. IndexOf işlevi dönecektir beri değeri yok olduğunda

cevap

9

bulmaktır sadece "(" konumuna 1 ekleyebilir. bir kesmek

private static string DecipherUserName (string user) {   
    int start = user.IndexOf("("); 
    if (start == -1) 
     return user; 
    return user.Substring (start+1).Replace(")", string.Empty); 
} 
+0

Not: Refactor'u, uzun vadede hissettiğim gibi sağlanan RegEx çözümü üzerinden Pax tarafından kabul ettim, bu daha RegEx'de daha fazla ustalaşana kadar daha sürdürülebilir olacaktır. Bu ve 1000 isimlerinden oluşan hızlı bir test, .0167195 ms'de Dize çözümünde .0077423 ms'de RegEx çözümüne sahipti. –

+0

Basit bir metin eşleşmesi için, RE'ler genellikle daha yavaştır (bir döngüde ekstra hız için bir kez derlenebilmelerine rağmen). Gerçek avantajları, daha karmaşık durumlar için (örneğin, parantez içindeki boşluklara izin verme ve çıkarma) kendi ifadeleriyle ortaya çıkmaktadır. Çok fazla öğrenmeye değer, o yüzden devam et. – paxdiablo

2

-1, sen

private static string DecipherUserName(string user) 
{   
    int start = user.IndexOf("("); 

    if (start > -1) 
    { 
     return user.Substring(start).Replace("(", string.Empty).Replace(")", string.Empty); 
    } 
    else 
    { 
     return user; 
    } 
} 
+0

Dizin varolduğunda Unutmayın, değer mevcut değil. Teşekkürler! –

20

Regexes kendine gönül yarası bir ton tasarruf edeceğiz böylece yararlıdır ... biraz farklı şeyler yapabilir mermiyi ısırmak ve onları öğrenmek. Bütün Shebang değil, sadece temeller.

Çalışacağınız bir regex "\ w + \ ((*. *)") - jsmith Match.Groups [1] dizininde olurdu.

Regexes almaya

kolay yollarından biri, ilk sizin beri yerine Sen gerekmez sonra eşleşmeleri tükürmek bir regex ve bazı metin yazın bildireceğiz bir web sitesi ...

+0

+1 regex için, doğru araç –

+0

olduğu için Paren kapalı kullanıcı adının boşluk içermeyen bir adla izlenmesi gereken açık bir gereksinim yoktur. "\ (. * \)" yeterli olmalıdır. – James

+0

Doğru araç ama yanlış RE - parantez olmadan bir kullanıcının durumunu ele alacak bir tane gerekir. Bunu yapın ve size bir oy vereceğim :-) – paxdiablo

5

Kind ... ^^

return user.Substring(user.IndexOf('(') + 1).TrimEnd(')'); 

user hiçbir parantez açma içeriyorsa, IndexOf()-1 döndürür, bir tane ekleriz, sıfır alır ve SubString() tüm dizeyi döndürür. Kullanıcının adı kapanış parantezi ile bitmediği sürece TrimEnd()'un hiçbir etkisi olmayacaktır. user endeksini verir IndexOf() bir parantez açma içeriyorsa

, birini ekleyerek Açma parantezi Skipp ve Substring() ile dize kalan kısmını çıkartmak. Son olarak, kapanış parantezini TrimEnd() ile kaldırıyoruz.

+0

Dize API'sinin güzel kullanımı. –

+0

Bu, niyetini çok iyi yansıtmıyor olsa da. –

+0

İlk satır: Bir tür kesmek ... ^^;) –

1

Ben

int start=user.IndexOf('('); 
if (start != -1) { 
    end = user.IndexOf(')', start); 
    return user.Substring(start+1,end-start-1); 
} else 
    return user; 

kullanmayı tercih ediyorum Ama bu sadece kozmetik bir değişimdir: IndexOf'un karakterleri kullanarak biraz daha hızlı olduğunu ve alt dize yöntemini kullanarak daha tam olarak ne yapılması gerektiği ifade etmek görünüyor (ve yöntemi) ... (basit olabilir) String.Split kullanılarak

söyledi

, Daniel L 'ın yöntem parantez birden çiftleri varsa daha sağlamdır (ama hatalı biçimlendirilmiş dizeleri ile çok iyi uğraşmaz ve zorundadır dize dizisi oluşturmak.

Her şeyden önce, normal ifadelere olan ilginizden kurtulmanızı öneririm, çünkü bu durum tam olarak istedikleri şeydir :-)

+0

@Martin - Eh, bu (un) sağlıklı bir hoşnutsuzluk (-_ ^) Altyazı hakkında daha etkileyici olan yorumunuz kesinlikle doğrudur. –

5

Kullanıcı dizgisi her zaman "Joe Smith (jsmith)" biçimindeyse, bu işe yaramalıdır.

private static string DecipherUserName(string user) 
{ 
    string[] names = user.Split(new char[] {'(', ')'}); 
    return names.Length > 2 ? names[1] : user; 
} 

Ve kullanıcı dize her zaman ise "Joe Smith (gozdemir)", bu her zaman çalışacaktır.

Sadece mizah amaçlı ikinci giriş.

İlgili konular