是否有一种优雅的方法来解析单词并在大写字母之前添加空格

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

AutomaticTrackingSystem 

 Automatic Tracking System 

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

没有正则表达式,你可以做类似的事情(或者使用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 

您可以使用外观,例如:

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

这打印( 如ideone.com上所示 ):

 Automatic Tracking System XML Editor 

正则表达式(?!^)(?=[AZ])由两个断言组成:

  • (?!^) – 即我们不在字符串的开头
  • (?=[AZ]) – 即我们就在大写字母之前

相关问题

  • 如何在Java中将CamelCase转换为人类可读的名称?
  • 正则表达式(?<=#)[^#]+(?=#)工作?

参考

  • regular-expressions.info/Lookarounds

分裂差异

当你有几个不同的规则,和/或你想要Split而不是Replace时,使用断言确实有所作为。 这个例子结合了两个:

 string[] tests = { "AutomaticTrackingSystem", "XMLEditor", "AnXMLAndXSLT2.0Tool", }; Regex r = new Regex( @" (?<=[AZ])(?=[AZ][az]) # UC before me, UC lc after me | (?<=[^AZ])(?=[AZ]) # 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(); } 

这打印( 如ideone.com上所示 ):

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

相关问题

  • Java分裂正在吃我的角色。
    • 有许多分裂零宽度匹配断言的例子

我刚刚写了一个函数来完成这个。 🙂

([az])([AZ])替换$1 $2 (或其他语言的\1 \2 )。

我也有([AZ]+)([AZ][az])的替换 – 这会将“NumberOfABCDThings”之类的内容转换为“ABCD事物的数量”

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

 Regex r1 = new Regex(@"([az])([AZ])"); Regex r2 = new Regex(@"([AZ]+)([AZ][az])"); NewString = r1.Replace( InputString , "$1 $2"); NewString = r2.Replace( NewString , "$1 $2"); 

(虽然可能有更复杂的写作方式)

如果您可能有标点符号或数字,我猜您可以尝试([^AZ])([AZ])进行第一场比赛。

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

显然,有一个反向正则表达式的选项:-)我们现在可以消除字符串反转,这是另一种方法:

 using System; using System.Linq; using System.Text.RegularExpressions; class MainClass { public static void Main (string[] args) { Regex ry = new Regex (@"([AZ][az]+|[AZ]+[AZ]|[AZ]|[^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 

如果您试图保持首字母缩写完整,请将“([^ AZ])([AZ])”替换为“\ 1 \ 2”,否则将“(。)([AZ])”替换为“\ 1 \ 2”。

试试这个:

 using System; using System.Linq; using System.Text.RegularExpressions; class MainClass { public static void Main (string[] args) { var rx = new Regex (@"([az]+[AZ]|[AZ][AZ]+|[AZ]|[^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有一个参数用于向后扫描字符串,因此不再需要上面单独的字符串反转:-)

只需使用这个linq one-liner :(完全适合我)

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