当前位置: 首页 > article >正文

C# 正则表达式完全指南

C# 正则表达式完全指南

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

1. 基础知识

1.1 命名空间导入

using System.Text.RegularExpressions;

1.2 基本使用

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 正则表达式选项

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 字符匹配

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 分组和捕获

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 替换操作

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 前瞻和后顾

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 验证器

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 文本处理器

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 静态编译正则表达式

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 性能考虑

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. 异常处理

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. 单元测试

[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集成。合理使用静态编译和缓存可以显著提高性能。


http://www.kler.cn/a/501370.html

相关文章:

  • Linux网络编程5——多路IO转接
  • JAVA之单例模式
  • 【前端】【CSS3】基础入门知识
  • 【C++】字符串中的 insert 方法深层分析
  • frp内网穿透
  • spring boot 支持jsonp请求
  • 2025年华数杯国际赛B题论文首发+代码开源 数据分享+代码运行教学
  • 无人机电池技术引领低空经济新篇章!
  • 【网络云SRE运维开发】2025第2周-每日【2025/01/12】小测-【第12章 rip路由协议】理论和实操考试题
  • 【黑灰产】假钱包推广套路
  • SpringBoot项目实战(41)--Beetl网页使用自定义函数获取新闻列表
  • Linux随记(十四)
  • R语言的正则表达式
  • ssh+frp+公网IP 实现远程访问家里的电脑
  • 力扣-数组-219 存在重复元素Ⅱ
  • OceanBase环境搭建与熟悉全攻略:开启分布式数据库探索之旅
  • 生态水文研究中的机器学习与数学建模方法选择
  • 代码随想录算法训练营第二十八天-贪心算法-55. 跳跃游戏
  • 青少年编程与数学 02-006 前端开发框架VUE 21课题、路由控制
  • 【杂谈】-50+个生成式人工智能面试问题(二)
  • POI在word中插入图片
  • git去除.idea
  • 向量检索的算法-精确向量检索
  • 线程安全问题介绍
  • 什么是卷积网络中的平移不变性?平移shft在数据增强中的意义
  • 1月11日