代码之家  ›  专栏  ›  技术社区  ›  leora Matt Lacey

有优雅的方法来分析一个词并在大写字母前加空格吗

  •  19
  • leora Matt Lacey  · 技术社区  · 14 年前

    我需要解析一些数据,我想转换

    AutomaticTrackingSystem
    

    Automatic Tracking System
    

    基本上在任何大写字母前加一个空格(当然除了第一个字母)

    7 回复  |  直到 8 年前
        1
  •  19
  •   Community CDub    12 年前

    如果没有regex,您可以执行以下操作(或者使用linq进行更简洁的操作):

    (注意:没有错误检查,应该添加)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace SO
    {
        class Program
        {
            static void Main(string[] args)
            {
                String test = "AStringInCamelCase";
                StringBuilder sb = new StringBuilder();
    
                foreach (char c in test)
                {
                    if (Char.IsUpper(c))
                    {
                        sb.Append(" ");
                    }
                    sb.Append(c);
                }
    
                if (test != null && test.Length > 0 && Char.IsUpper(test[0]))
                {
                    sb.Remove(0, 1);
                }
    
                String result = sb.ToString();
                Console.WriteLine(result);
            }
        }
    }
    

    这给出了输出

    A String In Camel Case
    
        2
  •  26
  •   Community CDub    7 年前

    您可以使用环视功能,例如:

    string[] tests = {
       "AutomaticTrackingSystem",
       "XMLEditor",
    };
    
    Regex r = new Regex(@"(?!^)(?=[A-Z])");
    foreach (string test in tests) {
       Console.WriteLine(r.Replace(test, " "));
    }
    

    这张照片( as seen on ideone.com ):

    Automatic Tracking System
    X M L Editor
    

    正则表达式 (?!^)(?=[A-Z]) 包含两个断言:

    • (?!^) -也就是说,我们还没有开始
    • (?=[A-Z]) -也就是说,我们就在大写字母之前

    相关问题

    工具书类


    平分差额

    当你有几个不同的规则和/或你想要的时候,使用断言真的会有很大的不同。 Split 而不是 Replace . 这个例子结合了这两个方面:

    string[] tests = {
       "AutomaticTrackingSystem",
       "XMLEditor",
       "AnXMLAndXSLT2.0Tool",
    };
    
    Regex r = new Regex(
       @"  (?<=[A-Z])(?=[A-Z][a-z])    # UC before me, UC lc after me
        |  (?<=[^A-Z])(?=[A-Z])        # Not UC before me, UC after me
        |  (?<=[A-Za-z])(?=[^A-Za-z])  # Letter before me, non letter after me
        ",
       RegexOptions.IgnorePatternWhitespace
    );
    foreach (string test in tests) {
       foreach (string part in r.Split(test)) {
          Console.Write("[" + part + "]");
       }
       Console.WriteLine();
    }
    

    这张照片( as seen on ideone.com ):

    [Automatic][Tracking][System]
    [XML][Editor]
    [An][XML][And][XSLT][2.0][Tool]
    

    相关问题

        3
  •  4
  •   Peter Boughton    14 年前

    我刚写了一个函数来做这个。:)

    替换 ([a-z])([A-Z]) 具有 $1 $2 (或) \1 \2 其他语言)。

    我还有一个替代品 ([A-Z]+)([A-Z][a-z]) 同样-这会将“number of abcd things”等转换为“number of abcd things”

    所以在C中,这看起来像:

    Regex r1 = new Regex(@"([a-z])([A-Z])");
    Regex r2 = new Regex(@"([A-Z]+)([A-Z][a-z])");
    
    NewString = r1.Replace( InputString , "$1 $2");
    NewString = r2.Replace( NewString , "$1 $2");
    

    (尽管可能有一种更为贴心的写作方式)

    如果你可能有标点或数字,我想你可以试试。 ([^A-Z])([A-Z]) 第一场比赛。

    嗯,使用lookbehind和lookahead编写这些正则表达式的另一种方法是只匹配位置并插入一个空格,即。 (?<=[a-z])(?=[A-Z]) (?<=[A-Z]+)(?=[A-Z][a-z]) 在这两种情况下,只替换为“”——不确定该方法是否有优势,但这是一种有趣的方法。:)

        4
  •  3
  •   Michael Buen    14 年前

    显然,reverse regex有一个选项:-)我们现在可以消除字符串反转,下面是另一种方法:

    using System;
    using System.Linq;
    using System.Text.RegularExpressions;
    
    class MainClass
    {
        public static void Main (string[] args)
        {
            Regex ry = new Regex
                  (@"([A-Z][a-z]+|[A-Z]+[A-Z]|[A-Z]|[^A-Za-z]+[^A-Za-z])", 
                  RegexOptions.RightToLeft);
    
    
            string[] tests = {
            "AutomaticTrackingSystem",
            "XMLEditor",
            "AnXMLAndXSLT2.0Tool",
            "NumberOfABCDThings",
            "AGoodMan",
            "CodeOfAGoodMan"
            };
    
    
            foreach(string t in tests)
            {
                Console.WriteLine("\n\n{0} -- {1}", t, ry.Replace(t, " $1"));   
            }
    
        }
    
    
    }
    

    输出:

    AutomaticTrackingSystem --  Automatic Tracking System
    
    
    XMLEditor --  XML Editor
    
    
    AnXMLAndXSLT2.0Tool --  An XML And XSLT 2.0 Tool
    
    
    NumberOfABCDThings --  Number Of ABCD Things
    
    
    AGoodMan --  A Good Man
    
    
    CodeOfAGoodMan --  Code Of A Good Man
    
        5
  •  0
  •   relet    14 年前

    如果您试图保持缩写词的完整性,请将“([^a-z])([a-z])”替换为“\1\2”, 否则将“(.)([a-z])”替换为“\1\2”。

        6
  •  0
  •   Michael Buen    14 年前

    试试这个:

    using System;
    using System.Linq;
    using System.Text.RegularExpressions;
    
    class MainClass
    {
        public static void Main (string[] args)
        {
            var rx = new Regex
                    (@"([a-z]+[A-Z]|[A-Z][A-Z]+|[A-Z]|[^A-Za-z][^A-Za-z]+)");
    
            string[] tests = {
            "AutomaticTrackingSystem",
            "XMLEditor",
            "AnXMLAndXSLT2.0Tool",
            "NumberOfABCDThings",
            "AGoodMan",
            "CodeOfAGoodMan"
            };
    
            foreach(string t in tests)
            {
                string y = Reverse(t);
                string x = Reverse( rx.Replace(y, @" $1") );
                Console.WriteLine("\n\n{0} -- {1}",y,x);    
            }
    
        }
    
        static string Reverse(string s)
        {
            var ca = s.ToCharArray();
            Array.Reverse(ca);
            string t = new string(ca);
            return t;
        }
    
    }
    

    输出:

    metsySgnikcarTcitamotuA -- Automatic Tracking System 
    
    
    rotidELMX -- XML Editor 
    
    
    looT0.2TLSXdnALMXnA -- An XML And XSLT 2.0 Tool 
    
    
    sgnihTDCBAfOrebmuN -- Number Of ABCD Things 
    
    
    naMdooGA -- A Good Man 
    
    
    naMdooGAfOedoC -- Code Of A Good Man 
    

    它的工作原理是向后扫描字符串,并使大写字母成为终止符。希望有一个regex参数可以向后扫描字符串,这样就不再需要上述单独的字符串反转了:—)

        7
  •  0
  •   Mykola Klymyuk    8 年前

    只需使用这个Linq One衬里:(对我来说很好)

    public static string SpaceCamelCase(string input)
    {
        return input.Aggregate(string.Empty, (old, x) => $"{old}{(char.IsUpper(x) ? " " : "")}{x}").TrimStart(' ');
    }