使用正则表达式将字符串转换为帕斯卡命名法

4

我正在尝试使用RegEx.Replace将字符串转换为帕斯卡命名法。使用正则表达式不是必需的,但我认为这可能会更容易。以下是我要转换的一些示例测试用例:

simple simon says       => SimpleSimonSays
SIMPLE SIMON SaYs       => SimpleSimonSays
simple_simon_says       => SimpleSimonSays
simple    simon    says => SimpleSimonSays
simpleSimonSays         => SimpleSimonSays
simple___simon___  says => SimpleSimonSays

我目前使用的方法不使用正则表达式,在上述5个例子中有4个可以正确处理:

internal static string GetPascalCaseName(string name)
{
    string s = System.Globalization.CultureInfo.CurrentCulture.
               TextInfo.ToTitleCase(name.ToLower()).Replace(" ", "").Replace("_", "");

    return s;
}

其中一个失败的例子是 simpleSimonSays。目前它返回的是 Simplesimonsays 而不是 SimpleSimonSays。我该如何在所有4种情况下使其正常工作呢? 编辑 因此,如果单词之间有空格或下划线,或者达到大写字符时,它们将被区分。多个空格和/或多个下划线应视为一个。基本上,空格和下划线应该被忽略,并被用作下一个字母应该是一个大写字母的信号。像这样:
simple_____simon___   says => SimpleSimonSays

3
你将如何确定'simple'和'simon'以及'simon'和'says'的起始和结束位置?我认为这是真正的问题,如果是一个没有确定每个单词之间起始/结束位置的单个字符串,那么如何确定大小写。 - Ingenioushax
就像 simpleSimonSays 这样的单词来说,并不存在分割大小写字母的边界。所以,除非您正在使用自然语言处理技术,否则正则表达式无法做到这一点。 - user557597
否则,使用\b([^\W_]+)(?:[ _]*([^\W_]+))*\b并在委托回调中使用捕获集合。 - user557597
把单词场景想象成这样,而不是使用_simpleSimonSays_,使用pkrltUdrXywaT - user557597
@sln - 我更新了我的问题,希望编辑更清晰。对于你的例子,"pkrltUdrXywaT" 应该变成 "PkrltUdrXywaT" - Icemanind
显示剩余6条评论
3个回答

1
我有一个解决你问题的技巧。使用正则表达式,将单词拆分并在没有空格或下划线的驼峰式单词中引入空格。修改你的方法如下:
internal static string GetPascalCaseName(string name)
{
    if (!name.Contains(" ")) {
        name = Regex.Replace(name, "(?<=[a-z])(?=[A-Z])", " ");
    }
    string s = System.Globalization.CultureInfo.CurrentCulture.
               TextInfo.ToTitleCase(name.ToLower()).Replace(" ", "").Replace("_", "");

    return s;
}

你的方法中新增了这一行代码:

name = Regex.Replace(name, "(?<=[a-z])(?=[A-Z])", " ");

通过在驼峰命名法单词之间引入空格,将其拆分,使它们像其他单词一样容易理解。

对于此输入,

simpleSimonSays

它输出这个:
SimpleSimonSays

对于其余的输入,它仍然有效。即使对于您部分使用驼峰命名法和部分使用空格或下划线的单词,此策略也适用。


pkrltUdrXywaT 应该如何大写? - user557597
这几乎可以工作。但是对于我的第二个例子不起作用。SIMPLE SIMON SaYs 变成了 SimpleSimonSaYs 而不是 SimpleSimonSays - Icemanind
@sln:我在那里没有看到任何问题。pkrltUdrXywaT 只需要成为 PkrltUdrXywaT,只有第一个字母变成大写字母。你还期望其他的吗? - Pushpesh Kumar Rajwanshi
@Icemanind:抱歉,我错过了你的一个无法工作的案例。我已经处理了你的“SIMPLE SIMON SaYs”输入,现在它会给你你想要的结果“SimpleSimonSays”。请检查我的更新代码。另外,如果你有其他情况,请让我知道。我将进一步调整代码并使其正常工作。 - Pushpesh Kumar Rajwanshi

0

这是一个没有使用正则表达式的解决方案。最后一个无法完成。

            string[] input = {
                "simple simon says",
                "SIMPLE SIMON SaYs",
                "simple_simon_says",
                "simple    simon    says",
                "simpleSimonSays"
                             };

            var temp = input.Select(x => x.Split(new char[] {' ', '_'}, StringSplitOptions.RemoveEmptyEntries).Select(y => y.Select((z,i) => (i == 0) ? z.ToString().ToUpper() : z.ToString().ToLower()))).ToArray();
            string[] output = temp.Select(x => string.Join("", x.Select(y => string.Join("",y)))).ToArray();

0

如果版本名称可以像 "abc simpleSimonSays" 这样,那就不可能了。或者需要添加更多规则。或者使用深度学习等方法 :)
编辑:
可能的代码(但没有包含 "abc simpleSimonSays"):

var s = "simple__simon_says __ Hi _ _,,, __coolWa";

var s1 = Regex.Replace(s, "[ _,]+", " ");
var s2 = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s1);
var s3 = s2.Replace(" ","");

// s1 = "simple simon says Hi coolWa"
// s2 = "Simple Simon Says Hi Coolwa"
// s3 = "SimpleSimonSaysHiCoolwa"

如果单词之间有空格、下划线或者遇到大写字母时(假设它是一个新单词的开头),则这些单词会被区分。因此,在你的例子中,应该是“AbcSimpleSimonSays”。 - Icemanind
a) SIMPLE SIMON SaYs => SimpleSimonSays b) abc simpleSimonSays => AbcSimpleSimonSays 程序不知道为什么 a) "Y" 应该变成小写的 "y" 但是 b) "S" 应该保持大写。 人类可以理解,但对于程序来说,只是在小写字母后面加上大写字母。 - AndrewF

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