C#中的正则表达式驼峰命名法

3
我正在尝试使用正则表达式将类似于“North Korea”的字符串转换为类似于“northKorea”的字符串 - 有人知道我如何在C#中实现这个目标吗?
谢谢。

3
为什么要使用正则表达式?为什么不直接将所有空格替换为空字符串并将第一个字符转换为小写? - Bazzz
7个回答

7

如果你知道所有输入的字符串都是标题格式(例如“朝鲜”),你可以简单地执行以下操作:

string input = "North Korea"; 
input = input.Replace(" ",""); //remove spaces
string output = char.ToLower(input[0]) + 
              input.Substring(1); //make first char lowercase
                                  // output = "northKorea"

如果您的输入中有一些不是标题大小写,您可以使用TextInfo.ToTitleCase。

string input = "NoRtH kORea"; 
input = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(input);
input = input.Replace(" ",""); //remove spaces
string output = char.ToLower(input[0]) + 
          input.Substring(1); //make first char lowercase
                              // output = "northKorea"

4

忘掉正则表达式。
你只需要一个驼峰命名转换算法:

在这里查看: http://www.codekeep.net/snippets/096fea45-b426-40fd-8beb-dec49d8a8662.aspx

使用这个:

string camelCase = ConvertCaseString(a, Case.CamelCase);

如果它离线,复制粘贴:

void Main() {
    string a = "background color-red.brown";
    string camelCase = ConvertCaseString(a, Case.CamelCase);
    string pascalCase = ConvertCaseString(a, Case.PascalCase);
}

/// <summary>
/// Converts the phrase to specified convention.
/// </summary>
/// <param name="phrase"></param>
/// <param name="cases">The cases.</param>
/// <returns>string</returns>
static string ConvertCaseString(string phrase, Case cases)
{
    string[] splittedPhrase = phrase.Split(' ', '-', '.');
    var sb = new StringBuilder();

    if (cases == Case.CamelCase)
    {
        sb.Append(splittedPhrase[0].ToLower());
        splittedPhrase[0] = string.Empty;
    }
    else if (cases == Case.PascalCase)
        sb = new StringBuilder();

    foreach (String s in splittedPhrase)
    {
        char[] splittedPhraseChars = s.ToCharArray();
        if (splittedPhraseChars.Length > 0)
        {
            splittedPhraseChars[0] = ((new String(splittedPhraseChars[0], 1)).ToUpper().ToCharArray())[0];
        }
        sb.Append(new String(splittedPhraseChars));
    }
    return sb.ToString();
}

enum Case
{
    PascalCase,
    CamelCase
}

1
+1 不错的方法,但感觉有点大材小用。不过,这仍然是好的和相关的信息,即使只是让原帖作者重新考虑他/她的正则表达式想法。 :) - Bazzz

3
你可以将其拆分并重新组合:

你可以只是将其拆分并重新组合:

string[] split = ("North Korea").Split(' ');

StringBuilder sb = new StringBuilder();

for (int i = 0; i < split.Count(); i++)
{
    if (i == 0)
        sb.Append(split[i].ToLower());
    else
        sb.Append(split[i]);
}

编辑:像Bazzz建议的那样,我改用了StringBuilder。


+1 我喜欢这种方法,但是字符串拼接对于性能和内存管理来说并不是一个好主意。也许你应该使用 StringBuilder 来展示相同的例子。 - Bazzz
我同意 @Bazzz 的观点,每次使用 Split/Concat 函数都会导致一只独角兽死亡。 - Jonathan Dickinson

2

这是在Paolo Falabella的答案基础上作为字符串扩展进行的,处理了一些边界情况,如空字符串。由于CamelCase和camelCase之间存在一些混淆,因此我称之为LowerCamelCase,正如维基百科上所描述的那样。我抵制了使用nerdCaps的诱惑。

internal static string ToLowerCamelCase( this string input )
{
    string output = "";            
    if( String.IsNullOrEmpty( input ) == false  )
    {
        output = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase( input ); //in case not Title Case
        output = output.Replace( " ", "" ); //remove any white spaces between words
        if( String.IsNullOrEmpty( output ) == false )  //handles the case where input is "  "
        {
            output = char.ToLower( output[0] ) + output.Substring( 1 ); //lowercase first (even if 1 character string)
        }
    }
    return output;
}

使用:

string test = "Foo Bar";
test = test.ToLowerCamelCase();
... //test is now "fooBar"

更新: toong 在评论中提出了一个很好的观点 - 这对于字形不起作用。请参阅 toong 提供的链接。如果您想为字形调整上面的代码,这里还有迭代字形的示例(这里)(这里)


1
我喜欢你的方法。一个非常小的问题(我想这在所有回答中都有):如果第一个字母由组合字符("a\u0304\u0308" = "ā̈")或代理对("\uD950\uDF21" = "��")组成,则 output[0] 可能会失败。你可能需要使用 StringInfo.GetNextTextElement - 参见:http://msdn.microsoft.com/en-us/library/y0hcb622.aspx - toong
@toong - 这是一个很好的观点。我已经更新了以引用您的评论,并添加了一些链接。 - acarlon

1

String::Split 绝对是我最讨厌的之一。此外,其他答案都没有涉及到:

  • 文化
  • 所有形式的单词分隔符
  • 数字
  • 以单词分隔符开头时会发生什么

我试图尽可能接近基类库代码中的内容:

static string ToCamelCaseInvariant(string value) { return ToCamelCase(value, true, CultureInfo.InvariantCulture); }
static string ToCamelCaseInvariant(string value, bool changeWordCaps) { return ToCamelCase(value, changeWordCaps, CultureInfo.InvariantCulture); }

static string ToCamelCase(string value) { return ToCamelCase(value, true, CultureInfo.CurrentCulture); }
static string ToCamelCase(string value, bool changeWordCaps) { return ToCamelCase(value, changeWordCaps, CultureInfo.CurrentCulture); }

/// <summary>
/// Converts the given string value into camelCase.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="changeWordCaps">If set to <c>true</c> letters in a word (apart from the first) will be lowercased.</param>
/// <param name="culture">The culture to use to change the case of the characters.</param>
/// <returns>
/// The camel case value.
/// </returns>
static string ToCamelCase(string value, bool changeWordCaps, CultureInfo culture)
{
    if (culture == null)
        throw new ArgumentNullException("culture");
    if (string.IsNullOrEmpty(value))
        return value;

    var result = new StringBuilder(value.Length);
    var lastWasBreak = true;
    for (var i = 0; i < value.Length; i++)
    {
        var c = value[i];
        if (char.IsWhiteSpace(c) || char.IsPunctuation(c) || char.IsSeparator(c))
        {
            lastWasBreak = true;
        }
        else if (char.IsNumber(c))
        {
            result.Append(c);
            lastWasBreak = true;
        }
        else
        {
            if (result.Length == 0)
            {
                result.Append(char.ToLower(c, culture));
            }
            else if (lastWasBreak)
            {
                result.Append(char.ToUpper(c, culture));
            }
            else if (changeWordCaps)
            {
                result.Append(char.ToLower(c, culture));
            }
            else
            {
                result.Append(c);
            }

            lastWasBreak = false;
        }
    }

    return result.ToString();
}

// Tests
'  This is a test. 12345hello world' = 'thisIsATest12345HelloWorld'
'--north korea' = 'northKorea'
'!nOrTH koreA' = 'northKorea'
'System.Console.' = 'systemConsole'

1
尝试以下操作:
var input = "Hi my name is Rony";
var subStrs = input.ToLower().Split(' ');
var output = "";

foreach(var s in subStrs)
{
   if(s!=subStrs[0])
      output += s.First().ToString().ToUpper() + String.Join("", s.Skip(1));
   else
      output += s;
}

应该得到 "hiMyNameIsRony" 作为输出。

0
    string toCamelCase(string s)
    {
        if (s.Length < 2) return s.ToLower();
        return Char.ToLowerInvariant(s[0]) + s.Substring(1);
    }

类似于Paolo Falabella的代码,但可以处理空字符串和1个字符的字符串。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接