在将CamelCase转换为带空格的字符串时忽略现有空格

时间:2015-06-05 08:33:50

标签: c# .net regex

我想将camelCasePascalCase个单词拆分为单独的单词集合。

到目前为止,我有:

Regex.Replace(value, @"(\B[A-Z]+?(?=[A-Z][^A-Z])|\B[A-Z]+?(?=[^A-Z]))", " $0", RegexOptions.Compiled);

它可以很好地将“TestWord”转换为“Test Word”并保留单个单词不受影响,例如Testing仍为Testing

但是,当我更喜欢ABCTest时,A B C Test会转换为ABC Test

3 个答案:

答案 0 :(得分:4)

尝试:

[A-Z][a-z]+|[A-Z]+(?=[A-Z][a-z])|[a-z]+|[A-Z]+

An example on Regex101

如何在CS中使用?

string strText = " TestWord asdfDasdf  ABCDef";

string[] matches = Regex.Matches(strText, @"[A-Z][a-z]+|[A-Z]+(?=[A-Z][a-z])|[a-z]+|[A-Z]+")
                .Cast<Match>()
                .Select(m => m.Value)
                .ToArray();

string result = String.Join(" ", matches);

result = 'Test Word asdf Dasdf ABC Def'

工作原理

在示例字符串中:

TestWord qwerDasdf
ABCTest Testing    ((*&^%$CamelCase!"£$%^^))
asdfAasdf
AaBbbCD

[A-Z][a-z]+匹配:

  • [0-4] Test
  • [4-8] Word
  • [13-18] Dasdf
  • [22-26] Test
  • [27-34] Testing
  • [45-50] Camel
  • [50-54] Case
  • [68-73] Aasdf
  • [74-76] Aa
  • [76-79] Bbb

[A-Z]+(?=[A-Z][a-z])匹配:

  • [19-22] ABC

[a-z]+匹配:

  • [9-13] qwer
  • [64-68] asdf

[A-Z]+匹配:

  • [79-81] CD

答案 1 :(得分:1)

这是我的尝试:

int main()
{
int array[100];
int i,n;
int init_asc =0,init_desc = 0;
int asc_Flag = 0,desc_Flag = 0;
int asc_prev,desc_prev;
cout << "\nEnter the no Of Numbers:\t";
cin >>n;
cout <<"\nEnter the numbers :\t";
for(i=0; i < n; i++){
    cin>> array[i];
}

for( i=0; i < n; i++ )
{
    if(array[i]%2 == 0)
    {
        if(init_asc==0)
        {
            init_asc =1;
            asc_prev = array[i];
        }
        else
        {
            if(asc_prev > array[i])
                asc_Flag = 1;
            else
                asc_prev = array[i];
        }
    }
    else
    {
        if(init_desc==0)
        {
            init_desc =1;
            desc_prev = array[i];
        }
        else
        {
            if(desc_prev < array[i])
                desc_Flag = 1;
            else
                desc_prev = array[i];
        }
    }
}

if(!(asc_Flag|desc_Flag))
    cout << "\nTrue\n";
else
    cout << "\nFalse\n";
 }

此正则表达式可与(?<!^|\b|\p{Lu})\p{Lu}+(?=\p{Ll}|\b)|(?<!^\p{Lu}*|\b)\p{Lu}(?=\p{Ll}|(?<!\p{Lu}*)\b) Regex.Replace一起用作替换字符串。

 $0

请参阅demo

正则表达式解释:

  • 包含2个替代方案,用于说明小写字母之前或之后的大写字母链。
  • Regex.Replace(value, @"(?<!^|\b|\p{Lu})\p{Lu}+(?=\p{Ll}|\b)|(?<!^\p{Lu}*|\b)\p{Lu}(?=\p{Ll}|(?<!\p{Lu}*)\b)", " $0", RegexOptions.Compiled); - 第一个匹配多个大写字母的替代方法,这些大写字母前面没有字符串开头,字边界或其他大写字母,后跟小写字母或单词边界,
  • (?<!^|\b|\p{Lu})\p{Lu}+(?=\p{Ll}|\b) - 匹配单个大写字母的第二个替代方案,该大写字母前面没有字符串的开头,后面是可选的大写字母,或者是单词边界,后跟小写字母或单词边界没有可选的大写字母。

答案 2 :(得分:0)

您是否要求使用正则表达式?说实话,我根本不会使用正则表达式。它们很难调试,也不是特别易读。

我会选择一种小型,可重复使用,易于测试的扩展方法:

class Program
{
    static void Main(string[] args)
    {
        string[] inputs = new[]
        {
            "ABCTest",
            "HelloWorld",
            "testTest$Test",
            "aaҚbb"
        };

        var output = inputs.Select(x => x.SplitWithSpaces(CultureInfo.CurrentUICulture));

        foreach (string x in output)
        {
            Console.WriteLine(x);
        }

        Console.Read();
    }
}

public static class StringExtensions
{
    public static bool IsLowerCase(this TextInfo textInfo, char input)
    {
        return textInfo.ToLower(input) == input;
    }

    public static string SplitWithSpaces(this string input, CultureInfo culture = null)
    {
        if (culture == null)
        {
            culture = CultureInfo.InvariantCulture;
        }
        TextInfo textInfo = culture.TextInfo;

        StringBuilder sb = new StringBuilder(input);

        for (int i = 1; i < sb.Length; i++)
        {
            int previous = i - 1;

            if (textInfo.IsLowerCase(sb[previous]))
            {
                int insertLocation = previous - 1;

                if (insertLocation > 0)
                {
                    sb.Insert(insertLocation, ' ');
                }

                while (i < sb.Length && textInfo.IsLowerCase(sb[i]))
                {
                    i++;
                }
            }                
        }

        return sb.ToString();
    }
}
相关问题