2015-04-28 39 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

相关问题