Traitement de Chaînes Windows - Exemples C#

Exemples complets de traitement de chaînes C# pour plateforme Windows incluant manipulation, division, jonction, expressions régulières et analyse de texte

💻 Opérations de Division et Jonction de Chaînes csharp

🟢 simple ⭐⭐

Techniques avancées de division et jonction de chaînes avec différents séparateurs, délimiteurs et logique de parsing personnalisée

⏱️ 20 min 🏷️ csharp, string, split, join, parsing, windows
Prerequisites: Basic C# string operations, LINQ basics
using System;
using System.Text;
using System.Linq;

class StringSplitJoin
{
    // 1. Basic string splitting
    public static void BasicStringSplitting()
    {
        Console.WriteLine("=== Basic String Splitting ===");

        string text = "Apple,Banana,Cherry,Date,Elderberry";
        string[] fruits = text.Split(',');

        Console.WriteLine($"Original text: {text}");
        Console.WriteLine("Split fruits:");
        foreach (string fruit in fruits)
        {
            Console.WriteLine($"  {fruit}");
        }
        Console.WriteLine($"Total fruits: {fruits.Length}");
    }

    // 2. Splitting with multiple delimiters
    public static void MultipleDelimiterSplitting()
    {
        Console.WriteLine("\n=== Multiple Delimiter Splitting ===");

        string data = "John,Doe;25|New York|Jane,Smith;30|Los Angeles";

        // Define delimiters
        char[] delimiters = { ',', ';', '|' };

        string[] parts = data.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);

        Console.WriteLine($"Original data: {data}");
        Console.WriteLine("Split parts:");
        for (int i = 0; i < parts.Length; i++)
        {
            Console.WriteLine($"  {i}: {parts[i]}");
        }

        // Parse into structured format
        Console.WriteLine("\nParsed records:");
        for (int i = 0; i < parts.Length; i += 3)
        {
            if (i + 2 < parts.Length)
            {
                Console.WriteLine($"  Name: {parts[i]} {parts[i+1]}, Age: {parts[i+2]}, City: {parts[i+3]}");
            }
        }
    }

    // 3. Advanced splitting with StringSplitOptions
    public static void AdvancedSplitOptions()
    {
        Console.WriteLine("\n=== Advanced Split Options ===");

        string textWithEmptyEntries = "Apple,,Banana,,,Cherry,Date,,";

        Console.WriteLine($"Original text: '{textWithEmptyEntries}'");

        // Split including empty entries
        string[] withEmpty = textWithEmptyEntries.Split(',');
        Console.WriteLine($"
Split with empty entries (length: {withEmpty.Length}):");
        for (int i = 0; i < withEmpty.Length; i++)
        {
            Console.WriteLine($"  [{i}]: '{withEmpty[i]}'");
        }

        // Split removing empty entries
        string[] withoutEmpty = textWithEmptyEntries.Split(',', StringSplitOptions.RemoveEmptyEntries);
        Console.WriteLine($"
Split without empty entries (length: {withoutEmpty.Length}):");
        for (int i = 0; i < withoutEmpty.Length; i++)
        {
            Console.WriteLine($"  [{i}]: '{withoutEmpty[i]}'");
        }

        // Split with trimming entries
        string[] trimmedEntries = textWithEmptyEntries.Split(',', StringSplitOptions.RemoveEmptyEntries)
                                                  .Select(s => s.Trim())
                                                  .ToArray();
        Console.WriteLine($"
Split with trimmed entries (length: {trimmedEntries.Length}):");
        for (int i = 0; i < trimmedEntries.Length; i++)
        {
            Console.WriteLine($"  [{i}]: '{trimmedEntries[i]}'");
        }
    }

    // 4. String.Join operations
    public static void StringJoining()
    {
        Console.WriteLine("\n=== String Joining ===");

        string[] words = { "Hello", "World", "in", "C#" };

        // Basic joining
        string joined = string.Join(" ", words);
        Console.WriteLine($"Basic join: '{joined}'");

        // Join with different separators
        string commaJoined = string.Join(", ", words);
        Console.WriteLine($"Comma join: '{commaJoined}'");

        string pipeJoined = string.Join(" | ", words);
        Console.WriteLine($"Pipe join: '{pipeJoined}'");

        // Join with prefix and suffix
        string bracketed = $"[{string.Join("][", words)}]";
        Console.WriteLine($"Bracketed: '{bracketed}'");

        // Join with numbers
        int[] numbers = { 1, 2, 3, 4, 5 };
        string numberString = string.Join("-", numbers);
        Console.WriteLine($"Numbers joined: '{numberString}'");

        // Join with custom formatting
        string[] items = { "Apple", 1.99, "Orange", 2.49 };
        string formatted = string.Join(" | ", items.Select(item => item.ToString().PadLeft(10)));
        Console.WriteLine($"Formatted join: '{formatted}'");
    }

    // 5. Split and Join with complex parsing
    public static void ComplexParsing()
    {
        Console.WriteLine("\n=== Complex Parsing ===");

        string csvData = @"Name,Age,City,Salary
John Doe,25,New York,50000
Jane Smith,30,Los Angeles,65000
Bob Johnson,35,Chicago,75000
Alice Brown,28,Houston,58000";

        string[] lines = csvData.Split(new[] { "\r\n", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries);

        Console.WriteLine("CSV Data Parsing:");
        Console.WriteLine(csvData);
        Console.WriteLine();

        Console.WriteLine("Parsed records:");
        string[] headers = lines[0].Split(',');

        for (int i = 1; i < lines.Length; i++)
        {
            string[] fields = lines[i].Split(',');
            if (fields.Length == headers.Length)
            {
                Console.WriteLine($"Record {i}:");
                for (int j = 0; j < headers.Length; j++)
                {
                    Console.WriteLine($"  {headers[j]}: {fields[j]}");
                }
                Console.WriteLine();
            }
        }

        // Reconstruct with modified data
        Console.WriteLine("Reconstructed with modified salaries (+10%):");
        var modifiedLines = lines.Select((line, index) =>
        {
            if (index == 0) return line; // Keep header

            string[] fields = line.Split(',');
            if (fields.Length >= 4 && double.TryParse(fields[3], out double salary))
            {
                double newSalary = salary * 1.1;
                fields[3] = newSalary.ToString("F2");
            }
            return string.Join(",", fields);
        });

        string reconstructed = string.Join("\n", modifiedLines);
        Console.WriteLine(reconstructed);
    }

    // 6. Split with string separators (not just characters)
    public static void StringSeparatorSplitting()
    {
        Console.WriteLine("\n=== String Separator Splitting ===");

        string text = "Item1---Separator---Item2---Separator---Item3";
        string[] parts = text.Split(new string[] { "---Separator---" }, StringSplitOptions.None);

        Console.WriteLine($"Original: {text}");
        Console.WriteLine("Split with string separator:");
        for (int i = 0; i < parts.Length; i++)
        {
            Console.WriteLine($"  Part {i + 1}: '{parts[i]}'");
        }

        // Example with HTML tags
        string html = "<div>Content1</div><div>Content2</div><div>Content3</div>";
        string[] contentParts = html.Split(new string[] { "<div>", "</div>" }, StringSplitOptions.RemoveEmptyEntries);

        Console.WriteLine($"\nOriginal HTML: {html}");
        Console.WriteLine("Extracted content:");
        for (int i = 0; i < contentParts.Length; i++)
        {
            Console.WriteLine($"  Content {i + 1}: '{contentParts[i]}'");
        }
    }

    // 7. Joining with StringBuilder for performance
    public static void StringBuilderJoining()
    {
        Console.WriteLine("\n=== StringBuilder Joining ===");

        // Large array for performance testing
        string[] largeArray = Enumerable.Range(1, 10000)
                                       .Select(i => $"Item{i}")
                                       .ToArray();

        var stopwatch = System.Diagnostics.Stopwatch.StartNew();

        // Method 1: string.Join (fast for small arrays)
        stopwatch.Restart();
        string result1 = string.Join(", ", largeArray);
        stopwatch.Stop();
        Console.WriteLine($"string.Join: {stopwatch.ElapsedMilliseconds}ms");

        // Method 2: StringBuilder (better for custom formatting)
        stopwatch.Restart();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < largeArray.Length; i++)
        {
            if (i > 0) sb.Append(", ");
            sb.Append(largeArray[i]);
        }
        string result2 = sb.ToString();
        stopwatch.Stop();
        Console.WriteLine($"StringBuilder: {stopwatch.ElapsedMilliseconds}ms");

        // Method 3: StringBuilder with capacity optimization
        stopwatch.Restart();
        StringBuilder optimizedSb = new StringBuilder(largeArray.Length * 10); // Estimate capacity
        for (int i = 0; i < largeArray.Length; i++)
        {
            if (i > 0) optimizedSb.Append(", ");
            optimizedSb.Append(largeArray[i]);
        }
        string result3 = optimizedSb.ToString();
        stopwatch.Stop();
        Console.WriteLine($"Optimized StringBuilder: {stopwatch.ElapsedMilliseconds}ms");

        // Verify results are the same
        Console.WriteLine($"\nResults are equal: {result1 == result2 && result2 == result3}");
        Console.WriteLine($"Result length: {result1.Length:N0} characters");
    }

    // 8. Splitting with count limit
    public static void SplitWithLimit()
    {
        Console.WriteLine("\n=== Splitting with Count Limit ===");

        string text = "One,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten";

        Console.WriteLine($"Original text: {text}");

        // Split with limit
        string[] limitedSplit = text.Split(',', 4);
        Console.WriteLine("\nSplit with max 4 parts:");
        for (int i = 0; i < limitedSplit.Length; i++)
        {
            Console.WriteLine($"  Part {i + 1}: '{limitedSplit[i]}'");
        }

        // Split with limit and remove empty
        string textWithEmpty = "A,B,,D,E,,F";
        string[] limitedAndClean = textWithEmpty.Split(new[] { ',' }, 5, StringSplitOptions.RemoveEmptyEntries);

        Console.WriteLine($"
Original: '{textWithEmpty}'");
        Console.WriteLine($"Split with max 5 parts, removing empty:");
        for (int i = 0; i < limitedAndClean.Length; i++)
        {
            Console.WriteLine($"  Part {i + 1}: '{limitedAndClean[i]}'");
        }
    }

    // 9. Custom split and join functions
    public static void CustomSplitJoinFunctions()
    {
        Console.WriteLine("\n=== Custom Split and Join Functions ===");

        string text = "word1 word2   word3	word4
word5  word6";

        Console.WriteLine($"Original text: '{text}'");

        // Custom split by whitespace
        string[] words = CustomSplitByWhitespace(text);
        Console.WriteLine("\nCustom whitespace split:");
        for (int i = 0; i < words.Length; i++)
        {
            Console.WriteLine($"  Word {i + 1}: '{words[i]}'");
        }

        // Custom join with prefix
        string prefixed = CustomJoinWithPrefix(words, "=> ", " <=");
        Console.WriteLine($"\nCustom prefixed join: '{prefixed}'");

        // Custom split with quote handling
        string csvWithQuotes = "\"John Doe\",\"New York\",\"Engineer\",\"75000\",\"Jane Smith\",\"Boston\",\"Designer\",\"65000\"";
        string[] csvFields = CustomCsvSplit(csvWithQuotes);

        Console.WriteLine($"
CSV with quotes: '{csvWithQuotes}'");
        Console.WriteLine("Parsed fields:");
        for (int i = 0; i < csvFields.Length; i++)
        {
            Console.WriteLine($"  Field {i + 1}: '{csvFields[i]}'");
        }
    }

    // Helper methods
    static string[] CustomSplitByWhitespace(string text)
    {
        return text.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
    }

    static string CustomJoinWithPrefix(string[] items, string prefix, string suffix)
    {
        if (items.Length == 0) return string.Empty;

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < items.Length; i++)
        {
            if (i > 0) sb.Append(" ");
            sb.Append(prefix).Append(items[i]).Append(suffix);
        }
        return sb.ToString();
    }

    static string[] CustomCsvSplit(string csv)
    {
        var fields = new System.Collections.Generic.List<string>();
        bool inQuotes = false;
        StringBuilder currentField = new StringBuilder();

        for (int i = 0; i < csv.Length; i++)
        {
            char c = csv[i];

            if (c == '"')
            {
                if (inQuotes && i + 1 < csv.Length && csv[i + 1] == '"')
                {
                    // Escaped quote
                    currentField.Append('"');
                    i++; // Skip next quote
                }
                else
                {
                    // Toggle quote state
                    inQuotes = !inQuotes;
                }
            }
            else if (c == ',' && !inQuotes)
            {
                // Field separator
                fields.Add(currentField.ToString());
                currentField.Clear();
            }
            else
            {
                currentField.Append(c);
            }
        }

        // Add last field
        fields.Add(currentField.ToString());

        return fields.ToArray();
    }

    // 10. Real-world example: Log file processing
    public static void LogFileProcessing()
    {
        Console.WriteLine("\n=== Log File Processing Example ===");

        string logContent = @"2024-01-15 10:30:45 [INFO] User login successful: john_doe
2024-01-15 10:31:12 [WARN] Password expiring soon: jane_smith
2024-01-15 10:32:01 [ERROR] Database connection failed: TimeoutException
2024-01-15 10:32:15 [INFO] User logout: john_doe
2024-01-15 10:33:22 [DEBUG] Cache cleared: 256 entries removed
2024-01-15 10:34:05 [ERROR] File not found: /path/to/missing/file.txt";

        Console.WriteLine("Log File Content:");
        Console.WriteLine(logContent);
        Console.WriteLine();

        // Parse log entries
        string[] logLines = logContent.Split(new[] { "\r\n", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries);

        var logEntries = logLines.Select(line =>
        {
            string[] parts = line.Split(new[] { ' ' }, 4);
            if (parts.Length >= 4)
            {
                return new
                {
                    Timestamp = $"{parts[0]} {parts[1]}",
                    Level = parts[2].Trim('[', ']'),
                    Message = parts[3]
                };
            }
            return null;
        }).Where(entry => entry != null).ToList();

        Console.WriteLine("Parsed Log Entries:");
        foreach (var entry in logEntries)
        {
            Console.WriteLine($"[{entry.Timestamp}] {entry.Level}: {entry.Message}");
        }

        // Group by log level
        Console.WriteLine("\nLog Summary by Level:");
        var groupedLogs = logEntries.GroupBy(e => e.Level)
                                   .Select(g => new { Level = g.Key, Count = g.Count() })
                                   .OrderByDescending(g => g.Count);

        foreach (var group in groupedLogs)
        {
            Console.WriteLine($"{group.Level}: {group.Count} entries");
        }

        // Export to CSV
        string csvHeader = "Timestamp,Level,Message";
        string csvRows = string.Join("\n", logEntries.Select(e =>
            $"\{e.Timestamp}\,\{e.Level}\,\{e.Message.Replace("\"", "\"\"")}\""));
        string csvOutput = csvHeader + "\n" + csvRows;

        Console.WriteLine("\nCSV Export:");
        Console.WriteLine(csvOutput);
    }

    static void Main(string[] args)
    {
        Console.WriteLine("=== C# String Splitting and Joining Demo ===\n");

        try
        {
            BasicStringSplitting();
            MultipleDelimiterSplitting();
            AdvancedSplitOptions();
            StringJoining();
            ComplexParsing();
            StringSeparatorSplitting();
            StringBuilderJoining();
            SplitWithLimit();
            CustomSplitJoinFunctions();
            LogFileProcessing();

            Console.WriteLine("\nAll string splitting and joining examples completed successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error in string operations demo: {ex.Message}");
        }
    }
}

💻 Remplacement et Transformation de Chaînes csharp

🟢 simple ⭐⭐⭐

Techniques avancées de remplacement de chaînes incluant formatage, conversion majuscules/minuscules, encodage et transformation de texte

⏱️ 25 min 🏷️ csharp, string, replacement, formatting, text processing, windows
Prerequisites: C# string operations, Regular expressions basics, LINQ
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;

class StringReplacement
{
    // 1. Basic string replacement
    public static void BasicStringReplacement()
    {
        Console.WriteLine("=== Basic String Replacement ===");

        string text = "The quick brown fox jumps over the lazy dog. The fox is clever.";

        Console.WriteLine($"Original text: {text}");

        // Replace simple string
        string replaced = text.Replace("fox", "cat");
        Console.WriteLine($"Replace 'fox' with 'cat': {replaced}");

        // Replace case-insensitive
        string caseInsensitive = Regex.Replace(text, "the", "a", RegexOptions.IgnoreCase);
        Console.WriteLine($"Replace 'the' (case-insensitive) with 'a': {caseInsensitive}");

        // Replace only whole words
        string wholeWord = Regex.Replace(text, @"the", "a", RegexOptions.IgnoreCase);
        Console.WriteLine($"Replace whole word 'the' with 'a': {wholeWord}");
    }

    // 2. Case conversion operations
    public static void CaseConversion()
    {
        Console.WriteLine("\n=== Case Conversion ===");

        string text = "Hello World! This is a TEST of cAsE ConVerSiOn.";

        Console.WriteLine($"Original: {text}");
        Console.WriteLine($"ToUpper(): {text.ToUpper()}");
        Console.WriteLine($"ToLower(): {text.ToLower()}");
        Console.WriteLine($"ToTitleCase(): {ToTitleCase(text)}");

        // Custom case conversion
        Console.WriteLine($"\nCustom conversions:");
        Console.WriteLine($"Toggle Case: {ToggleCase(text)}");
        Console.WriteLine($"Camel Case: {ToCamelCase(text)}");
        Console.WriteLine($"Snake Case: {ToSnakeCase(text)}");
        Console.WriteLine($"Kebab Case: {ToKebabCase(text)}");
    }

    // 3. String formatting and template replacement
    public static void StringFormatting()
    {
        Console.WriteLine("\n=== String Formatting ===");

        // String.Format
        string name = "John";
        int age = 30;
        string city = "New York";

        string formatted = string.Format("Name: {0}, Age: {1}, City: {2}", name, age, city);
        Console.WriteLine($"String.Format: {formatted}");

        // String interpolation
        string interpolated = $"Name: {name}, Age: {age}, City: {city}";
        Console.WriteLine($"Interpolation: {interpolated}");

        // Numeric formatting
        double price = 1234.56789;
        Console.WriteLine($"Price formatted: {price:C2}"); // Currency
        Console.WriteLine($"Price formatted: {price:N2}"); // Number with separators
        Console.WriteLine($"Price formatted: {price:F3}"); // Fixed decimal
        Console.WriteLine($"Price formatted: {price:P1}"); // Percentage

        // Date formatting
        DateTime now = DateTime.Now;
        Console.WriteLine($"Date: {now:yyyy-MM-dd HH:mm:ss}");
        Console.WriteLine($"Date: {now:dddd, MMMM d, yyyy}");

        // Custom template replacement
        string template = "Dear {{name}}, your order #{{order}} for {{quantity}} {{product}} is {{status}}.";
        Dictionary<string, string> values = new Dictionary<string, string>
        {
            { "name", "Jane Doe" },
            { "order", "12345" },
            { "quantity", "3" },
            { "product", "widgets" },
            { "status", "shipped" }
        };

        string result = ReplaceTemplate(template, values);
        Console.WriteLine($"\nTemplate replacement: {result}");
    }

    // 4. String padding and alignment
    public static void StringPaddingAlignment()
    {
        Console.WriteLine("\n=== String Padding and Alignment ===");

        string[] words = { "Apple", "Banana", "Cherry", "Date", "Elderberry", "Fig" };

        Console.WriteLine("Left-aligned (width 12):");
        foreach (string word in words)
        {
            Console.WriteLine($"'{word.PadRight(12)}'");
        }

        Console.WriteLine("\nRight-aligned (width 12):");
        foreach (string word in words)
        {
            Console.WriteLine($"'{word.PadLeft(12)}'");
        }

        Console.WriteLine("\nCenter-aligned (width 12):");
        foreach (string word in words)
        {
            Console.WriteLine($"'{PadCenter(word, 12)}'");
        }

        // Numeric formatting with alignment
        double[] numbers = { 123.45, 67.89, 1234.56, 1.23, 98765.43 };

        Console.WriteLine("\nNumbers aligned:");
        Console.WriteLine("Aligned right:");
        foreach (double num in numbers)
        {
            Console.WriteLine($"{num,10:N2}");
        }

        Console.WriteLine("Aligned left:");
        foreach (double num in numbers)
        {
            Console.WriteLine($"{num,-10:N2}");
        }
    }

    // 5. String cleaning and normalization
    public static void StringCleaningNormalization()
    {
        Console.WriteLine("\n=== String Cleaning and Normalization ===");

        string dirtyText = "   Hello   World!   \n\t   This   has   extra   spaces.   ";

        Console.WriteLine($"Original: '{dirtyText}'");

        // Trim and normalize spaces
        string cleaned = string.Join(" ", dirtyText.Split(new[] { ' ', '\t', '\n', '\r' },
                                                     StringSplitOptions.RemoveEmptyEntries));
        Console.WriteLine($"Cleaned: '{cleaned}'");

        // Remove all non-alphanumeric characters
        string text = "Hello, World! 123 @#$%^&*()";
        string alphanumeric = new string(text.Where(char.IsLetterOrDigit).ToArray());
        Console.WriteLine($"\nOriginal: '{text}'");
        Console.WriteLine($"Alphanumeric only: '{alphanumeric}'");

        // Remove diacritics (accents)
        string accented = "Café naïve résumé";
        string normalized = RemoveDiacritics(accented);
        Console.WriteLine($"\nWith accents: '{accented}'");
        Console.WriteLine($"Without accents: '{normalized}'");

        // Remove HTML tags
        string html = "<p>This is <strong>bold</strong> and <em>italic</em> text.</p>";
        string plainText = Regex.Replace(html, @"<[^>]*>", "");
        Console.WriteLine($"\nHTML: '{html}'");
        Console.WriteLine($"Plain text: '{plainText}'");
    }

    // 6. Advanced replacement with callbacks
    public static void AdvancedReplacement()
    {
        Console.WriteLine("\n=== Advanced Replacement ===");

        string text = "I have 2 apples, 3 bananas, and 5 oranges.";

        Console.WriteLine($"Original: {text}");

        // Replace numbers with their squares
        string squared = Regex.Replace(text, @"d+", m =>
        {
            int number = int.Parse(m.Value);
            return (number * number).ToString();
        });
        Console.WriteLine($"Numbers squared: {squared}");

        // Replace words with their lengths
        string wordLengths = Regex.Replace(text, @"[a-zA-Z]+", m =>
        {
            return m.Value.Length.ToString();
        });
        Console.WriteLine($"Word lengths: {wordLengths}");

        // Censor bad words with dynamic replacement
        string sentence = "This is stupid and dumb, but not idiotic.";
        string censored = Regex.Replace(sentence, @"(stupid|dumb|idiotic)", m =>
        {
            return new string('*', m.Length);
        }, RegexOptions.IgnoreCase);
        Console.WriteLine($"\nOriginal: {sentence}");
        Console.WriteLine($"Censored: {censored}");

        // Format currency
        string moneyText = "I have $1000, you have $25000, they have $500000";
        string formatted = Regex.Replace(moneyText, @"$([d,]+)", m =>
        {
            string cleanNumber = m.Groups[1].Value.Replace(",", "");
            if (decimal.TryParse(cleanNumber, out decimal amount))
            {
                return $"${amount:N0}";
            }
            return m.Value;
        });
        Console.WriteLine($"\nMoney text: {moneyText}");
        Console.WriteLine($"Formatted: {formatted}");
    }

    // 7. String encoding and decoding
    public static void StringEncodingDecoding()
    {
        Console.WriteLine("\n=== String Encoding and Decoding ===");

        string original = "Hello, 世界! 🌍";

        Console.WriteLine($"Original: {original}");

        // Convert to bytes and back
        byte[] utf8Bytes = Encoding.UTF8.GetBytes(original);
        string fromUtf8 = Encoding.UTF8.GetString(utf8Bytes);
        Console.WriteLine($"UTF-8 round-trip: {fromUtf8}");

        // URL encoding
        string urlText = "Hello World! @#$%^&*()";
        string urlEncoded = Uri.EscapeDataString(urlText);
        string urlDecoded = Uri.UnescapeDataString(urlEncoded);
        Console.WriteLine($"
URL: {urlText}");
        Console.WriteLine($"Encoded: {urlEncoded}");
        Console.WriteLine($"Decoded: {urlDecoded}");

        // Base64 encoding
        string base64Encoded = Convert.ToBase64String(utf8Bytes);
        byte[] base64Decoded = Convert.FromBase64String(base64Encoded);
        string fromBase64 = Encoding.UTF8.GetString(base64Decoded);
        Console.WriteLine($"
Base64 encoded: {base64Encoded}");
        Console.WriteLine($"Base64 decoded: {fromBase64}");

        // HTML encoding
        string htmlText = "<script>alert('XSS');</script>";
        string htmlEncoded = System.Web.HttpUtility.HtmlEncode(htmlText);
        string htmlDecoded = System.Web.HttpUtility.HtmlDecode(htmlEncoded);
        Console.WriteLine($"
HTML: {htmlText}");
        Console.WriteLine($"HTML encoded: {htmlEncoded}");
        Console.WriteLine($"HTML decoded: {htmlDecoded}");
    }

    // 8. String comparison and similarity
    public static void StringComparisonSimilarity()
    {
        Console.WriteLine("\n=== String Comparison and Similarity ===");

        string str1 = "Hello World";
        string str2 = "hello world";
        string str3 = "Hello World!";
        string str4 = "Hello Universe";

        Console.WriteLine($"str1: '{str1}'");
        Console.WriteLine($"str2: '{str2}'");
        Console.WriteLine($"str3: '{str3}'");
        Console.WriteLine($"str4: '{str4}'");

        // Different comparison methods
        Console.WriteLine($"
Comparisons:");
        Console.WriteLine($"str1 == str2: {str1 == str2}");
        Console.WriteLine($"str1.Equals(str2): {str1.Equals(str2)}");
        Console.WriteLine($"str1.Equals(str2, StringComparison.OrdinalIgnoreCase): {str1.Equals(str2, StringComparison.OrdinalIgnoreCase)}");

        // Levenshtein distance (edit distance)
        Console.WriteLine($"
Levenshtein distances:");
        Console.WriteLine($"str1 vs str2: {LevenshteinDistance(str1, str2)}");
        Console.WriteLine($"str1 vs str3: {LevenshteinDistance(str1, str3)}");
        Console.WriteLine($"str1 vs str4: {LevenshteinDistance(str1, str4)}");

        // Jaccard similarity
        Console.WriteLine($"
Jaccard similarities:");
        Console.WriteLine($"str1 vs str2: {JaccardSimilarity(str1, str2):F2}");
        Console.WriteLine($"str1 vs str3: {JaccardSimilarity(str1, str3):F2}");
        Console.WriteLine($"str1 vs str4: {JaccardSimilarity(str1, str4):F2}");
    }

    // 9. String tokenization and parsing
    public static void StringTokenizationParsing()
    {
        Console.WriteLine("\n=== String Tokenization and Parsing ===");

        // CSV parsing with quotes
        string csv = "\"John Doe\",\"New York\",\"Engineer\",\"75000\",\"Jane Smith\",\"Boston\",\"Designer\",\"65000\"";
        var csvFields = ParseCsv(csv);

        Console.WriteLine($"CSV: {csv}");
        Console.WriteLine("Parsed fields:");
        for (int i = 0; i < csvFields.Length; i++)
        {
            Console.WriteLine($"  {i}: '{csvFields[i]}'");
        }

        // JSON-like parsing (simplified)
        string jsonLike = "name:\"John\", age:30, city:\"New York\", active:true";
        var dict = ParseJsonLike(jsonLike);

        Console.WriteLine($"
JSON-like: {jsonLike}");
        Console.WriteLine("Parsed key-value pairs:");
        foreach (var kvp in dict)
        {
            Console.WriteLine($"  {kvp.Key}: {kvp.Value}");
        }

        // Tokenize by multiple separators
        string text = "Word1,word2;word3 word4|word5";
        char[] separators = { ',', ';', ' ', '|' };
        var tokens = text.Split(separators, StringSplitOptions.RemoveEmptyEntries);

        Console.WriteLine($"
Original: {text}");
        Console.WriteLine("Tokens:");
        for (int i = 0; i < tokens.Length; i++)
        {
            Console.WriteLine($"  {i}: '{tokens[i]}'");
        }
    }

    // 10. Real-world example: Template email generator
    public static void EmailTemplateGenerator()
    {
        Console.WriteLine("\n=== Email Template Generator ===");

        string template = @"
Dear {{customer_name}},

Thank you for your order #{{order_id}} placed on {{order_date}}.

Order Details:
{{#items}}
- {{name}} (Quantity: {{quantity}}, Price: ${{price}})
{{/items}}

Subtotal: ${{subtotal}}
Tax ({{tax_rate}}%): ${{tax}}
Total: ${{total}}

Your order will be shipped to:
{{shipping_address}}

{{#tracking_number}}
Tracking Number: {{tracking_number}}
{{/tracking_number}}

Best regards,
{{company_name}}
{{#support_email}}
Support: {{support_email}}
{{/support_email}}
";

        // Template data
        var data = new System.Collections.Generic.Dictionary<string, object>
        {
            { "customer_name", "John Doe" },
            { "order_id", "ORD-2024-001" },
            { "order_date", DateTime.Now.ToString("yyyy-MM-dd") },
            { "items", new[]
                {
                    new { name = "Laptop", quantity = 1, price = "999.99" },
                    new { name = "Mouse", quantity = 2, price = "25.50" },
                    new { name = "Keyboard", quantity = 1, price = "75.00" }
                }
            },
            { "subtotal", "1125.99" },
            { "tax_rate", "8.25" },
            { "tax", "92.89" },
            { "total", "1218.88" },
            { "shipping_address", "123 Main St\nNew York, NY 10001" },
            { "tracking_number", "1Z999AA10123456784" },
            { "company_name", "TechStore Inc." },
            { "support_email", "[email protected]" }
        };

        string email = ProcessEmailTemplate(template, data);
        Console.WriteLine("Generated Email:");
        Console.WriteLine(email);
    }

    // Helper methods
    static string ToTitleCase(string input)
    {
        TextInfo ti = CultureInfo.CurrentCulture.TextInfo;
        return ti.ToTitleCase(input.ToLower());
    }

    static string ToggleCase(string input)
    {
        return new string(input.Select(c => char.IsUpper(c) ? char.ToLower(c) : char.ToUpper(c)).ToArray());
    }

    static string ToCamelCase(string input)
    {
        string[] words = Regex.Split(input, @"[^a-zA-Z0-9]");
        return string.Concat(words.Where(w => w.Length > 0)
                                .Select((w, i) => i == 0 ? w.ToLower() : char.ToUpper(w[0]) + w.Substring(1).ToLower()));
    }

    static string ToSnakeCase(string input)
    {
        return string.Join("_", Regex.Split(input, @"(?=[A-Z])").Select(w => w.ToLower()));
    }

    static string ToKebabCase(string input)
    {
        return string.Join("-", Regex.Split(input, @"(?=[A-Z])").Select(w => w.ToLower()));
    }

    static string PadCenter(string input, int totalWidth)
    {
        int padding = totalWidth - input.Length;
        int leftPadding = padding / 2;
        int rightPadding = padding - leftPadding;
        return input.PadLeft(input.Length + leftPadding).PadRight(totalWidth);
    }

    static string ReplaceTemplate(string template, Dictionary<string, string> values)
    {
        string result = template;
        foreach (var kvp in values)
        {
            result = result.Replace($"{{{kvp.Key}}}", kvp.Value);
        }
        return result;
    }

    static string RemoveDiacritics(string input)
    {
        string normalized = input.Normalize(NormalizationForm.FormD);
        return new string(normalized.Where(c => CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark).ToArray());
    }

    static int LevenshteinDistance(string s1, string s2)
    {
        int[,] matrix = new int[s1.Length + 1, s2.Length + 1];

        for (int i = 0; i <= s1.Length; i++)
            matrix[i, 0] = i;

        for (int j = 0; j <= s2.Length; j++)
            matrix[0, j] = j;

        for (int i = 1; i <= s1.Length; i++)
        {
            for (int j = 1; j <= s2.Length; j++)
            {
                int cost = s1[i - 1] == s2[j - 1] ? 0 : 1;
                matrix[i, j] = Math.Min(
                    Math.Min(matrix[i - 1, j] + 1, matrix[i, j - 1] + 1),
                    matrix[i - 1, j - 1] + cost);
            }
        }

        return matrix[s1.Length, s2.Length];
    }

    static double JaccardSimilarity(string s1, string s2)
    {
        var set1 = new HashSet<char>(s1.ToLower());
        var set2 = new HashSet<char>(s2.ToLower());

        var intersection = new HashSet<char>(set1);
        intersection.IntersectWith(set2);

        var union = new HashSet<char>(set1);
        union.UnionWith(set2);

        return union.Count > 0 ? (double)intersection.Count / union.Count : 0;
    }

    static string[] ParseCsv(string csv)
    {
        var fields = new List<string>();
        bool inQuotes = false;
        StringBuilder currentField = new StringBuilder();

        for (int i = 0; i < csv.Length; i++)
        {
            char c = csv[i];

            if (c == '"')
            {
                if (inQuotes && i + 1 < csv.Length && csv[i + 1] == '"')
                {
                    currentField.Append('"');
                    i++;
                }
                else
                {
                    inQuotes = !inQuotes;
                }
            }
            else if (c == ',' && !inQuotes)
            {
                fields.Add(currentField.ToString());
                currentField.Clear();
            }
            else
            {
                currentField.Append(c);
            }
        }

        fields.Add(currentField.ToString());
        return fields.ToArray();
    }

    static Dictionary<string, string> ParseJsonLike(string json)
    {
        var dict = new Dictionary<string, string>();
        var pairs = json.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

        foreach (string pair in pairs)
        {
            var parts = pair.Split(new[] { ':' }, 2);
            if (parts.Length == 2)
            {
                string key = parts[0].Trim();
                string value = parts[1].Trim().Trim('"');
                dict[key] = value;
            }
        }

        return dict;
    }

    static string ProcessEmailTemplate(string template, Dictionary<string, object> data)
    {
        string result = template;

        // Simple variable replacement
        foreach (var kvp in data)
        {
            if (kvp.Value is string || kvp.Value.GetType().IsPrimitive)
            {
                result = result.Replace($"{{{{{kvp.Key}}}}}", kvp.Value.ToString());
            }
        }

        // Handle simple loops (simplified)
        result = Regex.Replace(result, @"{{#(\w+)}}.*?{{/\1}}", m =>
        {
            string key = m.Groups[1].Value;
            if (data.ContainsKey(key))
            {
                // Simplified handling - just show that there are items
                var items = data[key] as Array;
                return items?.Length > 0 ? $"
[{items.Length} items in {key}]
" : "";
            }
            return "";
        });

        return result;
    }

    static void Main(string[] args)
    {
        Console.WriteLine("=== C# String Replacement and Transformation Demo ===\n");

        try
        {
            BasicStringReplacement();
            CaseConversion();
            StringFormatting();
            StringPaddingAlignment();
            StringCleaningNormalization();
            AdvancedReplacement();
            StringEncodingDecoding();
            StringComparisonSimilarity();
            StringTokenizationParsing();
            EmailTemplateGenerator();

            Console.WriteLine("\nAll string replacement examples completed successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error in string replacement demo: {ex.Message}");
        }
    }
}

💻 Expressions Régulières et Correspondance de Modèles csharp

🟡 intermediate ⭐⭐⭐

Opérations avancées d'expressions régulières en C# incluant correspondance de modèles, validation, extraction et remplacement

⏱️ 30 min 🏷️ csharp, regex, pattern matching, text processing, windows
Prerequisites: C# string basics, Regex fundamentals
using System;
using System.Text.RegularExpressions;
using System.Linq;

class RegexPatternMatching
{
    // 1. Basic regex pattern matching
    public static void BasicRegexMatching()
    {
        Console.WriteLine("=== Basic Regex Pattern Matching ===");

        string text = "The quick brown fox jumps over the lazy dog. The fox is clever.";
        string pattern = @"fox";

        Console.WriteLine($"Text: {text}");
        Console.WriteLine($"Pattern: {pattern}");

        // Check if pattern exists
        bool containsPattern = Regex.IsMatch(text, pattern);
        Console.WriteLine($"Contains 'fox': {containsPattern}");

        // Find all matches
        MatchCollection matches = Regex.Matches(text, pattern);
        Console.WriteLine($"\nFound {matches.Count} matches:");
        foreach (Match match in matches)
        {
            Console.WriteLine($"  Match at position {match.Index}: '{match.Value}'");
        }

        // Find first match
        Match firstMatch = Regex.Match(text, pattern);
        if (firstMatch.Success)
        {
            Console.WriteLine($"
First match: '{firstMatch.Value}' at position {firstMatch.Index}");
        }
    }

    // 2. Email validation with regex
    public static void EmailValidation()
    {
        Console.WriteLine("\n=== Email Validation ===");

        string emailPattern = @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$";

        string[] testEmails = {
            "[email protected]",
            "[email protected]",
            "invalid.email",
            "user@localhost",
            "[email protected]",
            "[email protected]",
            "[email protected]",
            "user@domain."
        };

        Console.WriteLine("Testing email validation:");
        foreach (string email in testEmails)
        {
            bool isValid = Regex.IsMatch(email, emailPattern);
            Console.WriteLine($"  {email,-30} => {(isValid ? "Valid" : "Invalid")}");
        }
    }

    // 3. Phone number validation and formatting
    public static void PhoneNumberProcessing()
    {
        Console.WriteLine("\n=== Phone Number Processing ===");

        // Various phone number formats
        string[] phoneNumbers = {
            "123-456-7890",
            "(123) 456-7890",
            "123.456.7890",
            "1234567890",
            "+1 (123) 456-7890",
            "1-123-456-7890",
            "invalid-number"
        };

        // Regex pattern for US phone numbers
        string phonePattern = @"^(+?1[s-]?)?(?([0-9]{3}))?[s-]?([0-9]{3})[s-]?([0-9]{4})$";

        Console.WriteLine("Phone number validation and formatting:");
        foreach (string phone in phoneNumbers)
        {
            Match match = Regex.Match(phone, phonePattern);
            if (match.Success)
            {
                string areaCode = match.Groups[2].Value;
                string prefix = match.Groups[3].Value;
                string lineNumber = match.Groups[4].Value;
                string formatted = $"({areaCode}) {prefix}-{lineNumber}";

                Console.WriteLine($"  {phone,-20} => Valid -> {formatted}");
            }
            else
            {
                Console.WriteLine($"  {phone,-20} => Invalid");
            }
        }
    }

    // 4. Password strength validation
    public static void PasswordStrengthValidation()
    {
        Console.WriteLine("\n=== Password Strength Validation ===");

        string[] passwords = {
            "password",
            "Password123",
            "MySecurePass!",
            "ComplexP@ssw0rd#2024",
            "12345678",
            "Abc123",
            "VeryLongPasswordWithNumbers123AndSymbols!"
        };

        // Password strength requirements
        string minLengthPattern = @".{8,}";                    // At least 8 characters
        string uppercasePattern = @"[A-Z]";                     // At least one uppercase
        string lowercasePattern = @"[a-z]";                     // At least one lowercase
        string digitPattern = @"[0-9]";                         // At least one digit
        string specialPattern = @"[!@#$%^&*()_+-=[]{};':""\|,.<>/?]"; // At least one special char

        Console.WriteLine("Password strength analysis:");
        foreach (string password in passwords)
        {
            bool hasMinLength = Regex.IsMatch(password, minLengthPattern);
            bool hasUppercase = Regex.IsMatch(password, uppercasePattern);
            bool hasLowercase = Regex.IsMatch(password, lowercasePattern);
            bool hasDigit = Regex.IsMatch(password, digitPattern);
            bool hasSpecial = Regex.IsMatch(password, specialPattern);

            int strength = 0;
            if (hasMinLength) strength++;
            if (hasUppercase) strength++;
            if (hasLowercase) strength++;
            if (hasDigit) strength++;
            if (hasSpecial) strength++;

            string strengthLevel = strength switch
            {
                5 => "Very Strong",
                4 => "Strong",
                3 => "Medium",
                2 => "Weak",
                1 => "Very Weak",
                _ => "Invalid"
            };

            Console.WriteLine($"  {password,-35} => {strengthLevel}");
            Console.WriteLine($"    Min Length: {hasMinLength}, Upper: {hasUppercase}, Lower: {hasLowercase}, Digit: {hasDigit}, Special: {hasSpecial}");
        }
    }

    // 5. Extracting data from text
    public static void DataExtraction()
    {
        Console.WriteLine("\n=== Data Extraction ===");

        string text = @"Contact Information:
John Doe - Phone: (555) 123-4567, Email: [email protected]
Jane Smith - Phone: 555.987.6543, Email: [email protected]
Bob Johnson - Phone: +1 555 234 5678, Email: [email protected]";

        Console.WriteLine("Original text:");
        Console.WriteLine(text);

        // Extract emails
        string emailPattern = @"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Z|a-z]{2,}";
        MatchCollection emailMatches = Regex.Matches(text, emailPattern);

        Console.WriteLine("\nExtracted emails:");
        foreach (Match match in emailMatches)
        {
            Console.WriteLine($"  {match.Value}");
        }

        // Extract phone numbers
        string phonePattern = @"(?([0-9]{3}))?[s-]?([0-9]{3})[s-]?([0-9]{4})";
        MatchCollection phoneMatches = Regex.Matches(text, phonePattern);

        Console.WriteLine("\nExtracted phone numbers:");
        foreach (Match match in phoneMatches)
        {
            string formattedPhone = $"({match.Groups[1]}) {match.Groups[2]}-{match.Groups[3]}";
            Console.WriteLine($"  {match.Value} -> {formattedPhone}");
        }

        // Extract names (simple pattern)
        string namePattern = @"([A-Z][a-z]+ [A-Z][a-z]+)";
        MatchCollection nameMatches = Regex.Matches(text, namePattern);

        Console.WriteLine("\nExtracted names:");
        foreach (Match match in nameMatches)
        {
            Console.WriteLine($"  {match.Value}");
        }
    }

    // 6. String replacement with regex
    public static void StringReplacement()
    {
        Console.WriteLine("\n=== String Replacement ===");

        string text = "Visit our website at http://example.com or email us at [email protected]. Check out https://secure.example.com for secure access.";

        Console.WriteLine("Original text:");
        Console.WriteLine(text);

        // Replace URLs with HTML links
        string urlPattern = @"(https?://[^s]+)";
        string withLinks = Regex.Replace(text, urlPattern, "<a href='$1'>$1</a>");

        Console.WriteLine("\nWith HTML links:");
        Console.WriteLine(withLinks);

        // Censor bad words
        string badWordsPattern = @"(stupid|idiot|dumb)";
        string cleanText = "That was a stupid idea, not idiotic, but definitely not dumb!";
        string censoredText = Regex.Replace(cleanText, badWordsPattern, m => new string('*', m.Length), RegexOptions.IgnoreCase);

        Console.WriteLine($"\nOriginal: {cleanText}");
        Console.WriteLine($"Censored: {censoredText}");

        // Format currency
        string numbersText = "Prices: $1000, $25000, $500000, $7500000";
        string formattedNumbers = Regex.Replace(numbersText, @"$(d+)", m =>
        {
            if (decimal.TryParse(m.Groups[1].Value, out decimal amount))
            {
                return $"${amount:N0}";
            }
            return m.Value;
        });

        Console.WriteLine($"\nNumbers: {numbersText}");
        Console.WriteLine($"Formatted: {formattedNumbers}");
    }

    // 7. Advanced pattern: HTML tag processing
    public static void HtmlTagProcessing()
    {
        Console.WriteLine("\n=== HTML Tag Processing ===");

        string html = @"<div class='container'>
    <h1>Welcome to <span style='color: red'>Our Website</span></h1>
    <p>This is a <strong>paragraph</strong> with <em>emphasis</em>.</p>
    <a href='https://example.com'>Click here</a>
    <img src='image.jpg' alt='Sample Image' />
</div>";

        Console.WriteLine("HTML content:");
        Console.WriteLine(html);

        // Extract all tag names
        string tagPattern = @"<s*(w+)(?:s+[^>]*)?>";
        MatchCollection tagMatches = Regex.Matches(html, tagPattern);

        Console.WriteLine("\nAll HTML tags found:");
        foreach (Match match in tagMatches)
        {
            Console.WriteLine($"  {match.Groups[1].Value}");
        }

        // Extract attribute values
        string attributePattern = @"(w+)s*=s*['""](.*?)['""]";
        MatchCollection attributeMatches = Regex.Matches(html, attributePattern);

        Console.WriteLine("\nHTML attributes:");
        foreach (Match match in attributeMatches)
        {
            Console.WriteLine($"  {match.Groups[1].Value} = '{match.Groups[2].Value}'");
        }

        // Remove all HTML tags (get plain text)
        string plainText = Regex.Replace(html, @"<[^>]*>", "");
        plainText = Regex.Replace(plainText, @"s+", " ").Trim();

        Console.WriteLine($"\nPlain text: {plainText}");
    }

    // 8. Log file parsing with regex
    public static void LogFileParsing()
    {
        Console.WriteLine("\n=== Log File Parsing ===");

        string[] logLines = {
            "2024-01-15 10:30:45.123 [INFO] User login: john_doe from 192.168.1.100",
            "2024-01-15 10:31:12.456 [ERROR] Database connection failed: Timeout after 30s",
            "2024-01-15 10:32:01.789 [WARN] High CPU usage: 95% on server-web-01",
            "2024-01-15 10:33:22.012 [INFO] User logout: jane_smith session ended"
        };

        // Log pattern: timestamp [level] message
        string logPattern = @"^(d{4}-d{2}-d{2}sd{2}:d{2}:d{2}.d{3})s[([A-Z]+)]s(.*)$";

        Console.WriteLine("Parsed log entries:");
        foreach (string line in logLines)
        {
            Match match = Regex.Match(line, logPattern);
            if (match.Success)
            {
                string timestamp = match.Groups[1].Value;
                string level = match.Groups[2].Value;
                string message = match.Groups[3].Value;

                Console.WriteLine($"  Timestamp: {timestamp}");
                Console.WriteLine($"  Level: {level}");
                Console.WriteLine($"  Message: {message}");

                // Extract IP addresses if present
                if (Regex.IsMatch(message, @"d{1,3}.d{1,3}.d{1,3}.d{1,3}"))
                {
                    string ipPattern = @"(d{1,3}.d{1,3}.d{1,3}.d{1,3})";
                    Match ipMatch = Regex.Match(message, ipPattern);
                    Console.WriteLine($"  IP Address: {ipMatch.Groups[1].Value}");
                }

                // Extract percentages if present
                if (Regex.IsMatch(message, @"d+%"))
                {
                    string percentPattern = @"(d+)%";
                    Match percentMatch = Regex.Match(message, percentPattern);
                    Console.WriteLine($"  Percentage: {percentMatch.Groups[1].Value}%");
                }

                Console.WriteLine();
            }
        }
    }

    // 9. Performance considerations
    public static void RegexPerformance()
    {
        Console.WriteLine("\n=== Regex Performance Considerations ===");

        string largeText = string.Join(" ", Enumerable.Range(1, 10000)
                                                      .Select(i => $"Word{i} testing{Math.Pow(i, 2)} pattern{i%100}"));

        // Pattern to find all words ending with numbers
        string pattern = @"w+d+";

        var stopwatch = System.Diagnostics.Stopwatch.StartNew();

        // Test 1: Compiled regex (reuse)
        stopwatch.Restart();
        Regex compiledRegex = new Regex(pattern, RegexOptions.Compiled);
        MatchCollection compiledMatches = compiledRegex.Matches(largeText);
        stopwatch.Stop();
        Console.WriteLine($"Compiled regex: {stopwatch.ElapsedMilliseconds}ms, Found {compiledMatches.Count} matches");

        // Test 2: Static regex method (compiled internally)
        stopwatch.Restart();
        MatchCollection staticMatches = Regex.Matches(largeText, pattern);
        stopwatch.Stop();
        Console.WriteLine($"Static regex: {stopwatch.ElapsedMilliseconds}ms, Found {staticMatches.Count} matches");

        // Test 3: Non-compiled regex
        stopwatch.Restart();
        Regex nonCompiledRegex = new Regex(pattern);
        MatchCollection nonCompiledMatches = nonCompiledRegex.Matches(largeText);
        stopwatch.Stop();
        Console.WriteLine($"Non-compiled regex: {stopwatch.ElapsedMilliseconds}ms, Found {nonCompiledMatches.Count} matches");

        // Test 4: RegexOptions.IgnoreCase impact
        string textWithCases = "Hello hello HELLO HeLLo";
        string casePattern = "hello";

        stopwatch.Restart();
        bool caseSensitive = Regex.IsMatch(textWithCases, casePattern);
        stopwatch.Stop();
        Console.WriteLine($"
Case-sensitive: {stopwatch.ElapsedTicks} ticks, Found: {caseSensitive}");

        stopwatch.Restart();
        bool caseInsensitive = Regex.IsMatch(textWithCases, casePattern, RegexOptions.IgnoreCase);
        stopwatch.Stop();
        Console.WriteLine($"Case-insensitive: {stopwatch.ElapsedTicks} ticks, Found: {caseInsensitive}");
    }

    // 10. Custom regex patterns
    public static void CustomRegexPatterns()
    {
        Console.WriteLine("\n=== Custom Regex Patterns ===");

        // Credit card number validation
        string creditCardPattern = @"(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|3[0-9]{13}|6(?:011|5[0-9]{2})[0-9]{12})";
        string[] creditCards = { "4111111111111111", "5105105105105100", "378282246310005", "1234567890123456", "invalid-card" };

        Console.WriteLine("Credit card validation:");
        foreach (string card in creditCards)
        {
            bool isValid = Regex.IsMatch(card, creditCardPattern);
            string masked = card.Length > 4 ? "****-****-****-" + card.Substring(card.Length - 4) : card;
            Console.WriteLine($"  {masked} => {(isValid ? "Valid" : "Invalid")}");
        }

        // Social Security Number (US) format
        string ssnPattern = @"d{3}-d{2}-d{4}";
        string text = "John's SSN: 123-45-6789, Jane's SSN: 987-65-4321";

        Console.WriteLine($"
SSN extraction from: {text}");
        MatchCollection ssnMatches = Regex.Matches(text, ssnPattern);
        foreach (Match match in ssnMatches)
        {
            string ssn = match.Value;
            string masked = ssn.Substring(0, 7) + "****";
            Console.WriteLine($"  {masked}");
        }

        // Hex color codes
        string hexColorPattern = @"#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})";
        string cssText = "colors: #FF0000, #00FF00, #0000FF, #ABC, #123456, #invalid";

        Console.WriteLine($"
Hex color codes in: {cssText}");
        MatchCollection colorMatches = Regex.Matches(cssText, hexColorPattern);
        foreach (Match match in colorMatches)
        {
            Console.WriteLine($"  {match.Value}");
        }
    }

    static void Main(string[] args)
    {
        Console.WriteLine("=== C# Regular Expressions Demo ===\n");

        try
        {
            BasicRegexMatching();
            EmailValidation();
            PhoneNumberProcessing();
            PasswordStrengthValidation();
            DataExtraction();
            StringReplacement();
            HtmlTagProcessing();
            LogFileParsing();
            RegexPerformance();
            CustomRegexPatterns();

            Console.WriteLine("\nAll regex pattern matching examples completed successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error in regex demo: {ex.Message}");
        }
    }
}