Neatly processing the read text is necessary in almost all programs. string in C# provides a wealth of methods, including StringBuilder for iterative composition and Regex for pattern matching. We also point out the pitfall that the Number/Date parsing results may vary depending on culture.
Learning Objectives
- Know key methods such as
Trim/Split/Join/Replace/ToUpper/Contains/StartsWith - Utilizes the interpolation string
$"..."and format specifiers (F2,yyyy-MM-dd, etc.) - I know that
StringBuilderis fast for iterative synthesis. - Learn the basic usage of
Regex.IsMatch/Match/Matches - Understand that parsing results may vary depending on
CultureInfo
Key concepts
1) Common string methods
" hello ".Trim(); // "hello"
"a,b,c".Split(','); // ["a", "b", "c"]
string.Join("-", ["a","b"]); // "a-b"
"abc".Replace("b", "X"); // "aXc"
"hi".ToUpper(); // "HI"
"hello".Contains("ll"); // true
"hello".StartsWith("he"); // true
string is immutable (Part 02), so all methods return a new string.
2) Interpolation string $"..."
This is the cleanest synthesis method that inserts variables and expressions as is.
double pi = 3.14159;
DateTime now = DateTime.Now;
Console.WriteLine($"Pi is about {pi:F2}"); //2 decimal places
Console.WriteLine($"Today is {now:yyyy-MM-dd}");
Console.WriteLine($"Sort: |{42,5}|"); //Width 5, right aligned
The format specifier follows the colon. F2 is 2 decimal places, and yyyy-MM-dd is the ISO date.
3) StringBuilder — building text iteratively
If you accumulate strings with += inside a loop, you will get a new object each time. As the number of times increases, it becomes very slow. StringBuilder is fast because it is concatenated to an internal buffer.
using System.Text;
var sb = new StringBuilder();
for (int i = 0; i < 1000; i++)
sb.Append(i).Append(',');
string result = sb.ToString();
For synthesis less than a dozen times, just + is fine. If repeated hundreds to thousands of times, StringBuilder.
4) Regex — regular expressions
Regular expression in the System.Text.RegularExpressions namespace.
using System.Text.RegularExpressions;
Regex.IsMatch("hello123", @"\d+"); //true (includes numbers?)
var m = Regex.Match("Spell #4242", @"\d+");
if (m.Success) Console.WriteLine(m.Value); // "4242"
foreach (Match x in Regex.Matches("a1 b22 c333", @"\d+"))
Console.WriteLine(x.Value); // 1, 22, 333
@"..." is a verbatim string that accepts backslashes — works well with regular expressions.
5) Culture Trap
Parsing of numbers or dates is affected by system culture. For example, in Germany , is the decimal point.
using System.Globalization;
//Korea, UK, etc.: “3.14” is 3.14
//Germany (de-DE): "3.14" is interpreted as 314, and "3,14" is interpreted as 3.14
decimal de = decimal.Parse("3,14", CultureInfo.GetCultureInfo("de-DE"));
decimal inv = decimal.Parse("3.14", CultureInfo.InvariantCulture);
Like-Settings/CSV/Log The machine-readable format always specifies CultureInfo.InvariantCulture. Use system culture only for user screen display.
See as example
Example 1 — StringMethods: Frequently used methods
string s = " Hello, C# World ";
Console.WriteLine($"Original: [{s}]");
Console.WriteLine($"Trim : [{s.Trim()}]");
Console.WriteLine($"Upper : [{s.Trim().ToUpper()}]");
Console.WriteLine($"Replace : [{s.Trim().Replace("C#", "DotNet")}]");
string[] parts = "Apples, bananas, cherries".Split(',');
Console.WriteLine($"Split: {parts.Length} → {string.Join(" | ", parts)}");
Console.WriteLine($"Contains 'C#' : {s.Contains("C#")}");
Console.WriteLine($"StartsWith ' ' : {s.StartsWith(" ")}");
Execution result
Original: [Hello, C# World]
Trim : [Hello, C# World]
Upper : [HELLO, C# WORLD]
Replace : [Hello, DotNet World]
Split: 3 → apple | Banana | cherry
Contains 'C#' : True
StartsWith ' ' : True
Note: You can chain transformations using method chaining.
Example 2 — Interpolation: Interpolation string and format
double pi = 3.14159265;
int score = 87;
DateTime now = new DateTime(2025, 5, 18, 14, 30, 0);
Console.WriteLine($"pi: {pi:F2}");
Console.WriteLine($"Score: {score,5} points"); //Width 5, right aligned
Console.WriteLine($"Score (left): {score,-5}|"); //Negative Width → Left Align
Console.WriteLine($"Date: {now:yyyy-MM-dd HH:mm}");
Console.WriteLine($"Percent: {0.873:P1}"); //1-digit percentage
Execution result
Pi: 3.14
Score: 87 points
Score (left): 87 |
Date: 2025-05-18 14:30
Percent: 87.3%
Note: ,N is the width, :F2 is the format, and if both are used together, it becomes {value,10:F2}.
Example 3 — StringBuilderUse: Iterative synthesis performance
using System.Text;
var sb = new StringBuilder();
sb.Append("[");
for (int i = 1; i <= 5; i++)
{
if (i > 1) sb.Append(", ");
sb.Append(i);
}
sb.Append("]");
Console.WriteLine(sb.ToString());
Console.WriteLine($"Length: {sb.Length}");
//Performance note: If you have a few hundred loops or more, this is very fast compared to +=
Execution result
[1, 2, 3, 4, 5]
Length: 15
Note: For short synthesis, + is sufficient, but the more iterations, the greater the benefit of StringBuilder.
Example 4 — RegexBasics: Regular expression basics
using System.Text.RegularExpressions;
string text = "Please send inquiries to [email protected] or [email protected].";
//1) Included or not
bool hasDigit = Regex.IsMatch("Spell #42", @"\d+");
Console.WriteLine($"Include numbers? {hasDigit}");
//2) First match
Match first = Regex.Match("Price 1500 won", @"\d+");
Console.WriteLine($"First number: {first.Value}");
//3) Extract all emails
foreach (Match m in Regex.Matches(text, @"[\w\.-]+@[\w\.-]+\.\w+"))
{
Console.WriteLine($"Mail: {m.Value}");
}
Execution result
Include numbers? True
First number: 1500
Email: [email protected]
Email: [email protected]
Note: Practical email regular expressions are much more complex — these are simple patterns for learning.
Example 5 — Culture: Same string, different results
using System.Globalization;
string s = "3,14";
decimal de = decimal.Parse(s, CultureInfo.GetCultureInfo("de-DE"));
decimal inv;
bool ok = decimal.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out inv);
Console.WriteLine($"de-DE interpretation: {de}"); // 3.14
Console.WriteLine($"Invariant interpretation: ok={ok}, value={inv}"); //',' in thousands is 314 or failure.
//Safe machine format
decimal price = 1234.56m;
Console.WriteLine($"Machine Format: {price.ToString(CultureInfo.InvariantCulture)}");
Execution result
de-DE interpretation: 3.14
Invariant interpretation: ok=True, value=314
Machine Format: 1234.56
Memo: Always read and write CSV/configuration files as InvariantCulture. Use user culture only for UI display.
Common Mistakes
- Combining strings with
+=in a loop — If there are many times, useStringBuilder. - Compare user input without
Trim— fails due to spaces at both ends. - In the regular expression, escape it twice like
\\d— use the verbatim string of@"\d+". - Ignoring culture when parsing numbers — Results vary depending on the operating environment locale.
InvariantCulturefor data such as CSV/JSON. - Use
==for case comparison —string.Equals(a, b, StringComparison.OrdinalIgnoreCase)is safe.
Cleanup
Trim/Split/Join/Replaceare everyday tools- Composite interpolates string
$"..."+ format specifier - If repeated a lot,
StringBuilder - Pattern matching is
Regex.IsMatch/Match/Matches - Data format parsing specifies
CultureInfo.InvariantCulture
Try it yourself
cd src/StringMethods && dotnet run
cd ../Interpolation && dotnet run
cd ../StringBuilderUse && dotnet run
cd ../RegexBasics && dotnet run
cd ../Culture && dotnet run