【问题标题】:Converting string to Pascal Case using RegEx使用 RegEx 将字符串转换为 Pascal 大小写
【发布时间】:2018-11-13 19:40:46
【问题描述】:

我正在尝试使用 RegEx.Replace 将字符串转换为 Pascal 大小写。 RegEx 不是必需的,但我认为它可能会更容易。以下是我尝试转换的一些示例测试用例:

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

我目前使用的方法没有使用 RegEx,它在上面 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

【问题讨论】:

  • 您将如何确定“simple”和“simon”以及“simon”和“says”的开始和结束位置?我认为这是真正的问题,如果每个单词之间没有确定开始/结束的单个字符串,您如何确定一个单词的结尾和另一个单词的开头以进行大小写?
  • simpleSimonSays这样的单个词而言,提取大小写是没有边界的。因此,除非您使用自然语言处理,否则正则表达式永远不会这样做。
  • 否则,\b([^\W_]+)(?:[ _]*([^\W_]+))*\b 并在委托回调中使用捕获集合。
  • 想想这样的单字场景,而不是使用 simpleSimonSays 使用 pkrltUdrXywaT
  • @Ingenioushax - 我更新了我的问题。如果单词之间有空格或下划线,或者遇到大写字符(假设它是新单词的开头),则单词会被区分

标签: c# regex


【解决方案1】:

我有一个技巧可以解决你的问题。使用正则表达式,拆分单词并在单词中为没有空格或下划线的单词引入空格,即驼峰式大小写(如 simpleSimonSays)。修改你的方法到这个,

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应该如何大写?
  • 这几乎可以工作。但它不适用于我的第二个示例。 SIMPLE SIMON SaYs 变为 SimpleSimonSaYs 而不是 SimpleSimonSays
  • @sln:我看不出有什么问题。 pkrltUdrXywaT 将简单地变为 PkrltUdrXywaT,其中只有第一个字母发生变化并变为大写字母。你还期待别的吗?
  • @Icemanind:抱歉,我错过了你的一个案例,它不起作用。我已经处理了您的“SIMPLE SIMON SaYs”输入,现在它会为您提供您想要的结果“SimpleSimonSays”。请检查我更新的代码。另外,如果您有其他情况,请告诉我。我将进一步调整代码并使其工作。
【解决方案2】:

这是没有正则表达式的解决方案。最后一个做不到。

            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();

【讨论】:

    【解决方案3】:

    如果可以是“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"
    • 我的意思是不同 a)SIMPLE SIMON SaYs => SimpleSimonSays b)abc simpleSimonSays => AbcSimpleSimonSays 程序不知道为什么 a)"Y" 应该变成 "y" 但 b)"S" 应该离开大的。人类可以理解,但对于程序 - 只是一个接一个的大字母
    猜你喜欢
    • 2011-02-15
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    相关资源
    最近更新 更多