将字符串中的字符替换为下一个字符的大写形式(帕斯卡命名法)

4
我希望能够将字符串中所有下划线替换为其后面字符的大写字母。例如:_my_string_ 变为:MyString ;同样地:my_string 变为 MyString
是否有更简单的方法来实现这个功能呢?目前我使用了以下代码(假设输入中没有连续两个下划线):
        StringBuilder sb = new StringBuilder();
        int i;
        for (i = 0; i < input.Length - 1; i++)
        {
            if (input[i] == '_')
                sb.Append(char.ToUpper(input[++i]));
            else if (i == 0)
                sb.Append(char.ToUpper(input[i]));
            else
                sb.Append(input[i]);
        }
        if (i < input.Length && input[i] != '_')
            sb.Append(input[i]);

        return sb.ToString();

虽然这并非完全相关,但我觉得应该对回答中提供的实现进行一些数据测试。以下是每个实现使用 1000000 次字符串迭代 "_my_string_121_a_" 所需的毫秒数:

Achilles: 313
Raj: 870
Damian: 7916
Dmitry: 5380
Equalsk: 574

使用的方法:

        Stopwatch stp = new Stopwatch();
        stp.Start();
        for (int i = 0; i < 1000000; i++)
        {
            sb = Test("_my_string_121_a_");
        }
        stp.Stop();
        long timeConsumed= stp.ElapsedMilliseconds;

最终,我认为我会选择Raj的实现方式,因为它非常简单易懂。

@Achilles,请告诉我我的解决方案是否适用于您。如果不是您要求的内容,我可以将其删除。有些新手无法理解问题,但会对逻辑提出抱怨。 - Rajshekar Reddy
@RajshekarReddy 看起来对我有效。我正在测试它。 - Faheem
@Achilles 谢谢。你有没有打算处理空格?如果是这样,你想要将空格后的第一个字符大写吗? - Rajshekar Reddy
我只是在将数据库中的变量名转换,不打算处理空格。我认为在变量名中不允许使用空格。 - Faheem
@Achilles 感谢您的澄清。 - Rajshekar Reddy
显示剩余4条评论
6个回答

7

使用 System.Globalization 命名空间中的 ToTitleCase 方法实现此操作。

static string toCamel(string input)
{        
    TextInfo info = CultureInfo.CurrentCulture.TextInfo;
    input= info.ToTitleCase(input).Replace("_", string.Empty);
    return input;
} 

enter image description here


1
但这不是问题,如果字符串是“hello_mynameis_john”,结果将是“helloMynameisJohn”。 - Alfie Goodacre
因为代码不仅仅会在问题的上下文中使用,这会如何影响我的答案?我已经回答了所提出的问题。就这个问题而言,我的答案给出了他期望的输出。 - Rajshekar Reddy
我并不是说你的解决方案完全错误,但它并不正确,因为它非常脆弱,在除了给定情况之外的99%的情况下都无法工作。 - Alfie Goodacre
@AlfieGoodacre 的问题在于你没有足够的经验去理解一个给定的问题。你需要始终考虑“为什么”被问及,而不是急于想“如何”去做... 祝编码愉快! - Rajshekar Reddy
@AlfieGoodacre 要积极对待哦,我只是想帮助你。 - Rajshekar Reddy
显示剩余18条评论

4

短一点的(正则表达式),但我怀疑它是否更好(正则表达式不太易读):

  string source = "_my_string_123__A_";

  // MyString123A  
  string result = Regex
     // _ + lower case Letter -> upper case letter (thanks to Wiktor Stribiżew)
    .Replace(source, @"(_+|^)(\p{Ll})?", match => match.Groups[2].Value.ToUpper())
     // all the other _ should be just removed
    .Replace("_", "");

为什么要使用可选组?为什么不匹配小写字母并将其捕获到第1组中呢?另外,短的正则表达式模式非常易读。 - Wiktor Stribiżew
@Wiktor Stribiżew:我必须删除所有下划线,无论它们是否后跟字母(例如,尾部下划线)。 - Dmitry Bychenko
我相信你仍然可以像 @"_+(.)" 一样增强它,并将 source.TrimEnd('_') 传递给正则表达式。 - Wiktor Stribiżew
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Dmitry Bychenko
无法处理 my_string:返回 myString,期望值为:MyString。 - Faheem
1
@Achilles:toCamel的预期行为,对于toTitle,由于你已经改变了问题,你需要稍微改变一下实现方式(请参见我的编辑)。请查看我的编辑。 - Dmitry Bychenko

3
循环遍历每个字符并根据需要将其转换为大写。
public string GetNewString(string input)
{
    var convert = false;
    var sb = new StringBuilder();

    foreach (var c in input)
    {
        if (c == '_')
        {
            convert = true;
            continue;
        }

        if (convert)
        {
            sb.Append(char.ToUpper(c));
            convert = false;
            continue;
        }

        sb.Append(c);
    }

    return sb.ToString().First().ToString().ToUpper() + sb.ToString().Substring(1);
}

使用方法:

GetNewString("my_string");
GetNewString("___this_is_anewstring_");
GetNewString("___this_is_123new34tring_");

输出:

我的字符串
这是一个新字符串
这是123的新34个字符串


2

尝试使用正则表达式:

var regex = new Regex("^[a-z]|_[a-z]?");
var result = regex.Replace("my_string_1234", x => x.Value== "_" ? "" : x.Value.Last().ToString().ToUpper());

测试使用的软件版本:

my_string   -> MyString
_my_string  -> MyString
_my_string_ -> MyString

我的_123_ 将成为 My123。 - Damian
不适用于 my_string:返回 myString,预期结果是 MyString。 - Faheem
@Achilles 等等,第一个字符应该始终大写吗? - Alfie Goodacre
@AlfieGoodacre 是的,不完全是驼峰命名法...我明白混淆的原因所在。 - Faheem
1
@Achilles,我已经修复了my_string的问题。 - Damian
显示剩余2条评论

1

您需要将蛇形命名法转换为驼峰命名法,您可以使用这段代码,它对我有效。

  var x ="_my_string_".Split(new[] {"_"}, StringSplitOptions.RemoveEmptyEntries)
                .Select(s => char.ToUpperInvariant(s[0]) + s.Substring(1, s.Length - 1))
                .Aggregate(string.Empty, (s1, s2) => s1 + s2);

x = MyString

enter image description here


1
    static string toCamel(string input)
    {
        StringBuilder sb = new StringBuilder();
        int i;
        for (i = 0; i < input.Length; i++)
        {
            if ((i == 0) || (i > 0 && input[i - 1] == '_'))
                sb.Append(char.ToUpper(input[i]));
            else
                sb.Append(char.ToLower(input[i]));
        }
        return sb.ToString();
    }

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