C# 正则表达式完全指南

C# 正则表达式完全指南

C#通过 System.Text.RegularExpressions 命名空间提供强大的正则表达式支持。本指南将详细介绍C#中正则表达式的使用方法、性能优化和最佳实践。

1. 基础知识

1.1 命名空间导入

csharp 复制代码
using System.Text.RegularExpressions;

1.2 基本使用

csharp 复制代码
public class RegexBasics
{
    public void BasicExamples()
    {
        string text = "Hello, my phone is 123-456-7890";

        // 创建正则表达式对象
        Regex regex = new Regex(@"\d+");

        // 检查是否匹配
        bool isMatch = regex.IsMatch(text);

        // 查找第一个匹配
        Match match = regex.Match(text);
        if (match.Success)
        {
            Console.WriteLine($"Found: {match.Value}");
        }

        // 查找所有匹配
        MatchCollection matches = regex.Matches(text);
        foreach (Match m in matches)
        {
            Console.WriteLine($"Found: {m.Value}");
        }
    }
}

1.3 正则表达式选项

csharp 复制代码
public class RegexOptions
{
    public void OptionsExample()
    {
        // 不区分大小写
        Regex caseInsensitive = new Regex(@"hello", RegexOptions.IgnoreCase);

        // 多行模式
        Regex multiline = new Regex(@"^start", RegexOptions.Multiline);

        // 忽略空白字符和注释
        Regex ignored = new Regex(@"
            \d+  # 匹配数字
            \s*  # 可选的空白字符
            \w+  # 匹配单词
        ", RegexOptions.IgnorePatternWhitespace);

        // 编译正则表达式以提高性能
        Regex compiled = new Regex(@"\d+", RegexOptions.Compiled);
    }
}

2. 正则表达式语法

2.1 字符匹配

csharp 复制代码
public class CharacterMatching
{
    public void MatchingExamples()
    {
        string text = "C# 10.0 is awesome! Price: $99.99";

        // 匹配数字
        Regex digits = new Regex(@"\d+");
        foreach (Match m in digits.Matches(text))
        {
            Console.WriteLine($"Number: {m.Value}");
        }

        // 匹配单词
        Regex words = new Regex(@"\w+");
        var wordMatches = words.Matches(text)
            .Cast<Match>()
            .Select(m => m.Value)
            .ToList();

        // 匹配空白字符
        string[] parts = Regex.Split(text, @"\s+");

        // 自定义字符类
        Regex vowels = new Regex(@"[aeiou]", RegexOptions.IgnoreCase);
        var vowelMatches = vowels.Matches(text)
            .Cast<Match>()
            .Select(m => m.Value)
            .ToList();
    }
}

2.2 分组和捕获

csharp 复制代码
public class GroupingExample
{
    public void GroupExamples()
    {
        string text = "John Smith, Jane Doe, Bob Johnson";
        
        // 基本分组
        Regex regex = new Regex(@"(\w+)\s(\w+)");
        foreach (Match match in regex.Matches(text))
        {
            Console.WriteLine($"Full name: {match.Groups[0].Value}");
            Console.WriteLine($"First name: {match.Groups[1].Value}");
            Console.WriteLine($"Last name: {match.Groups[2].Value}");
        }

        // 命名分组
        Regex namedRegex = new Regex(@"(?<first>\w+)\s(?<last>\w+)");
        foreach (Match match in namedRegex.Matches(text))
        {
            Console.WriteLine($"First: {match.Groups["first"].Value}");
            Console.WriteLine($"Last: {match.Groups["last"].Value}");
        }
    }
}

3. 高级特性

3.1 替换操作

csharp 复制代码
public class ReplacementOperations
{
    public string ReplaceExample(string text)
    {
        // 简单替换
        string result1 = Regex.Replace(text, @"\d+", "X");

        // 使用MatchEvaluator委托
        string result2 = Regex.Replace(text, @"\d+", match =>
        {
            int number = int.Parse(match.Value);
            return (number * 2).ToString();
        });

        // 使用命名组的替换
        Regex regex = new Regex(@"(?<first>\w+)\s(?<last>\w+)");
        string result3 = regex.Replace(text, "${last}, ${first}");

        return result3;
    }
}

3.2 前瞻和后顾

csharp 复制代码
public class LookAroundExample
{
    public void LookAroundDemo()
    {
        string text = "Price: $100, Cost: $50";

        // 正向前瞻
        Regex positiveAhead = new Regex(@"\d+(?=\s*dollars)");

        // 负向前瞻
        Regex negativeAhead = new Regex(@"\d+(?!\s*dollars)");

        // 正向后顾
        Regex positiveBehind = new Regex(@"(?<=\$)\d+");

        // 负向后顾
        Regex negativeBehind = new Regex(@"(?<!\$)\d+");
    }
}

4. 实用工具类

4.1 验证器

csharp 复制代码
public class Validator
{
    private static readonly Regex EmailRegex = new Regex(
        @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$",
        RegexOptions.Compiled);

    private static readonly Regex PhoneRegex = new Regex(
        @"^1[3-9]\d{9}$",
        RegexOptions.Compiled);

    private static readonly Regex PasswordRegex = new Regex(
        @"^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$",
        RegexOptions.Compiled);

    public static bool IsValidEmail(string email)
    {
        if (string.IsNullOrEmpty(email)) return false;
        return EmailRegex.IsMatch(email);
    }

    public static bool IsValidPhone(string phone)
    {
        if (string.IsNullOrEmpty(phone)) return false;
        return PhoneRegex.IsMatch(phone);
    }

    public static bool IsValidPassword(string password)
    {
        if (string.IsNullOrEmpty(password)) return false;
        return PasswordRegex.IsMatch(password);
    }
}

4.2 文本处理器

csharp 复制代码
public class TextProcessor
{
    private static readonly Regex UrlRegex = new Regex(
        @"https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+[^\s]*",
        RegexOptions.Compiled);

    private static readonly Regex HtmlTagRegex = new Regex(
        @"<[^>]+>",
        RegexOptions.Compiled);

    public static IEnumerable<string> ExtractUrls(string text)
    {
        if (string.IsNullOrEmpty(text)) return Enumerable.Empty<string>();
        return UrlRegex.Matches(text)
            .Cast<Match>()
            .Select(m => m.Value);
    }

    public static string StripHtmlTags(string html)
    {
        if (string.IsNullOrEmpty(html)) return string.Empty;
        return HtmlTagRegex.Replace(html, string.Empty);
    }

    public static string CleanWhitespace(string text)
    {
        if (string.IsNullOrEmpty(text)) return string.Empty;
        return Regex.Replace(text.Trim(), @"\s+", " ");
    }
}

5. 性能优化

5.1 静态编译正则表达式

csharp 复制代码
public class RegexOptimization
{
    // 使用静态字段存储编译后的正则表达式
    private static readonly Regex CompiledRegex = new Regex(
        @"\d+",
        RegexOptions.Compiled);

    // 使用Lazy<T>延迟初始化
    private static readonly Lazy<Regex> LazyRegex = 
        new Lazy<Regex>(() => new Regex(@"\d+", RegexOptions.Compiled));

    public void OptimizedExample()
    {
        // 使用编译后的正则表达式
        bool isMatch = CompiledRegex.IsMatch("123");

        // 使用延迟初始化的正则表达式
        bool lazyMatch = LazyRegex.Value.IsMatch("123");
    }
}

5.2 性能考虑

csharp 复制代码
public class PerformanceConsiderations
{
    // 1. 使用适当的选项
    private static readonly Regex FastRegex = new Regex(
        @"\d+",
        RegexOptions.Compiled | RegexOptions.ExplicitCapture);

    // 2. 避免过度使用通配符
    private static readonly Regex BetterRegex = new Regex(
        @"[^/]*foo[^/]*",  // 比 .*foo.* 更高效
        RegexOptions.Compiled);

    // 3. 使用非捕获组
    private static readonly Regex NonCapturingRegex = new Regex(
        @"(?:\d+)(?:[a-z]+)",  // 使用(?:)表示非捕获组
        RegexOptions.Compiled);
}

6. 异常处理

csharp 复制代码
public class RegexExceptionHandling
{
    public static Regex CreateSafeRegex(string pattern)
    {
        try
        {
            return new Regex(pattern, RegexOptions.Compiled);
        }
        catch (ArgumentException ex)
        {
            throw new ArgumentException($"Invalid regex pattern: {ex.Message}", ex);
        }
    }

    public static bool SafeIsMatch(string input, string pattern)
    {
        try
        {
            return Regex.IsMatch(input, pattern);
        }
        catch (RegexMatchTimeoutException ex)
        {
            Console.WriteLine($"Regex matching timed out: {ex.Message}");
            return false;
        }
        catch (ArgumentException ex)
        {
            Console.WriteLine($"Invalid regex pattern: {ex.Message}");
            return false;
        }
    }
}

7. 单元测试

csharp 复制代码
[TestClass]
public class ValidatorTests
{
    [TestMethod]
    public void TestEmailValidation()
    {
        Assert.IsTrue(Validator.IsValidEmail("test@example.com"));
        Assert.IsTrue(Validator.IsValidEmail("user@domain.co.uk"));
        Assert.IsFalse(Validator.IsValidEmail("invalid.email"));
        Assert.IsFalse(Validator.IsValidEmail("@domain.com"));
    }

    [TestMethod]
    public void TestPhoneValidation()
    {
        Assert.IsTrue(Validator.IsValidPhone("13812345678"));
        Assert.IsFalse(Validator.IsValidPhone("12345678"));
        Assert.IsFalse(Validator.IsValidPhone("2381234567"));
    }

    [TestMethod]
    public void TestTextProcessing()
    {
        string html = "<p>Hello</p><div>World</div>";
        Assert.AreEqual(
            "HelloWorld",
            TextProcessor.StripHtmlTags(html)
        );

        string text = "  multiple   spaces   here  ";
        Assert.AreEqual(
            "multiple spaces here",
            TextProcessor.CleanWhitespace(text)
        );
    }
}

总结

C#的正则表达式实现具有以下特点:

  1. 强大的Regex类支持
  2. 编译选项提供高性能
  3. LINQ集成
  4. 完整的Unicode支持

最佳实践:

  1. 使用静态编译的Regex对象提高性能
  2. 合理使用RegexOptions
  3. 处理超时和异常情况
  4. 编写完整的单元测试
  5. 使用命名捕获组提高可读性

注意事项:

  1. Regex对象创建开销大,应该重用
  2. 考虑使用Compiled选项提高性能
  3. 处理RegexMatchTimeoutException
  4. 注意内存使用

记住:在C#中使用正则表达式时,要充分利用.NET框架提供的功能,如编译选项和LINQ集成。合理使用静态编译和缓存可以显著提高性能。

相关推荐
wlyang66619 分钟前
4. scala高阶之隐式转换与泛型
大数据·开发语言·后端·spark·scala
JovaZou2 小时前
[Python学习日记-75] 计算机基础与网络
开发语言·网络·python·网络协议·学习·tcp/ip·计算机网络
五行星辰4 小时前
Servlet与JSP:Java的秘密花园入口
java·开发语言·servlet
代码驿站5205 小时前
Scala语言的软件工程
开发语言·后端·golang
Code花园5 小时前
Objective-C语言的多线程编程
开发语言·后端·golang
Rverdoser5 小时前
接口项目架构流程图-thinkphp6-rabbitmq
开发语言·microsoft·ruby
Jelena技术达人5 小时前
利用 Python 爬虫获取 1688 关键字 API 接口
开发语言·爬虫·python
graceyun5 小时前
C语言初阶习题【23】输出数组的前5项之和
c语言·开发语言·算法
喵手6 小时前
Java中将特征向量转换为矩阵的实现
java·开发语言·矩阵
晚安~~7 小时前
协同过滤算法商品推荐系统|Java|SpringBoot|VUE|
java·开发语言·maven