2015-04-28 40 views
1

我有一個很大的XML文件,其中包含實現破折號分隔的命名約定的標記名稱。我如何使用C#將標記名稱轉換爲駝峯命名約定?通過C#將破折號分隔的字符串轉換爲camelCase

規則是: 1。轉換所有字符爲小寫 2.大寫的第一個字符每一劃線 3.拆下後的所有短劃線

轉換之前

<foo-bar> 
<a-b-c></a-b-c> 
</foo-bar> 

轉換後

<fooBar> 
<aBC></aBC> 
</fooBar> 

下面是一個有效的代碼示例,但它的處理速度很慢 - 我想有更好的方法來實現我的目標。

string ConvertDashToCamelCase(string input) 
{ 
    input = input.ToLower(); 
    char[] ca = input.ToCharArray(); 
    StringBuilder sb = new StringBuilder(); 

    for(int i = 0; i < ca.Length; i++) 
    { 
     if(ca[i] == '-') 
     { 
      string t = ca[i + 1].ToString().toUpper(); 
      sb.Append(t); 
      i++; 
     } 
     else 
     { 
      sb.Append(ca[i].ToString()); 
     } 
    } 

    return sb.ToString(); 
} 
+0

提供一些代碼,以便我們可以幫助您...我們不會爲您完成這項工作。 –

+0

好的 - 代碼示例添加到我的OP。正如你所看到的,我蠻橫地強迫我穿過人物。此方法有效,但速度很慢。我希望找到更清潔,更快捷的解決方案。 – Jed

+0

可能的重複[http://stackoverflow.com/questions/17186641/...](http://stackoverflow.com/questions/17186641/how-do-i-make-letters-to-uppercase-after-除了在大寫字母后刪除特殊字符之外,每個特定字符都是一組字符)。 –

回答

5

你原來的代碼是緩慢的原因是因爲你打電話ToString得到處都是不必要的。這是沒有必要的。也不需要中間數組char。以下內容應該比使用String.Split的版本快得多,速度也更快。

string ConvertDashToCamelCase(string input) 
{ 
    StringBuilder sb = new StringBuilder(); 
    bool caseFlag = false; 
    for (int i = 0; i < input.Length; ++i) 
    { 
     char c = input[i]; 
     if (c == '-') 
     { 
      caseFlag = true; 
     } 
     else if (caseFlag) 
     { 
      sb.Append(char.ToUpper(c)); 
      caseFlag = false; 
     } 
     else 
     { 
      sb.Append(char.ToLower(c)); 
     } 
    } 
    return sb.ToString(); 
} 

我不打算聲稱以上是最快的可能。事實上,有幾個明顯的優化可以節省一些時間。但上述內容清晰明瞭:易於理解。

關鍵是caseFlag,您用它來表示複製的下一個字符應該設置爲大寫。另外請注意,我不會自動將整個字符串轉換爲小寫字母。沒有理由,因爲無論如何你都會看到每個角色,並且可以在那個時候進行適當的轉換。

這裏的想法是,代碼沒有做任何比它絕對必須的工作。

2
string ConvertDashToCamelCase(string input) 
{ 
    string[] words = input.Split('-'); 

    words = words.Select(element => wordToCamelCase(element)); 

    return string.Join("", words); 
} 

string wordToCamelCase(string input) 
{ 
    return input.First().ToString().ToUpper() + input.Substring(1).ToLower(); 
} 
+0

我沒有機器可以試用此代碼,但是這樣可以使用像' tag-content'這樣的標籤嗎?也就是說,如果標籤持有一個本身連字符的值,該怎麼辦? –

+0

@ s.m .:這段代碼和OP的代碼假設你想對整個字符串進行轉換。如果你想駱駝式的標籤而不是內容,你必須自己分開。 –

+0

@JimMischel OP明確寫道:「我如何使用C#將**標記名**轉換爲駝峯命名約定?」。這就是爲什麼我想警告可能會破壞XML內容,OP可能沒有想到這一點。換句話說,我提供了一雙額外的眼睛。 –

1

以下是@Jim Mischel答案的更新版本,它會忽略內容 - 即它只會使用camelCase標籤名稱。

string ConvertDashToCamelCase(string input) 
{ 
    StringBuilder sb = new StringBuilder(); 
    bool caseFlag = false; 
    bool tagFlag = false; 
    for(int i = 0; i < input.Length; i++) 
    { 
     char c = input[i]; 
     if(tagFlag) 
     { 
      if (c == '-') 
      { 
       caseFlag = true; 
      } 
      else if (caseFlag) 
      { 
       sb.Append(char.ToUpper(c)); 
       caseFlag = false; 
      } 
      else 
      { 
       sb.Append(char.ToLower(c)); 
      } 
     } 
     else 
     { 
      sb.Append(c); 
     } 

     // Reset tag flag if necessary 
     if(c == '>' || c == '<') 
     { 
      tagFlag = (c == '<'); 
     } 

    } 
    return sb.ToString(); 
} 
+0

我想你需要在輸入標籤時重置'caseFlag'。否則就像'內容 xxx'將導致'內容 xxx'(即bar標籤將被大寫)。我的功能遭受同樣的問題,因爲我對您的要求的理解是您將標記名稱傳遞給函數,而不是整行XML文本。 –

+1

@JimMischel - 事實證明,caseFlag設置爲true後,最終會有一個結束標記(>)的字符。當char是結束標記時,將滿足「else if(caseFlag)」條件。這意味着caseFlag將始終重置爲false。換句話說,你的代碼依然可以正常工作。 – Jed

相關問題