是否有一种优雅的方法来解析单词并在大写字母之前添加空格
我需要解析一些数据,我想转换
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(' '); }