You can use lookarounds, e.g:
string[] tests = {
"AutomaticTrackingSystem",
"XMLEditor",
};
Regex r = new Regex(@"(?!^)(?=[A-Z])");
foreach (string test in tests) {
Console.WriteLine(r.Replace(test, " "));
}
This prints (as seen on ideone.com):
Automatic Tracking System
X M L Editor
The regex (?!^)(?=[A-Z])
consists of two assertions:
(?!^)
- i.e. we're not at the beginning of the string
(?=[A-Z])
- i.e. we're just before an uppercase letter
Related questions
References
Splitting the difference
Here's where using assertions really make a difference, when you have several different rules, and/or you want to Split
instead of Replace
. This example combines both:
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();
}
This prints (as seen on ideone.com):
[Automatic][Tracking][System]
[XML][Editor]
[An][XML][And][XSLT][2.0][Tool]
Related questions
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…