C# 高级教程(3)—— 深入探究正则表达式

        在 C# 的编程世界中,正则表达式是一个强大且实用的工具,它能帮助开发者高效地处理文本检索和匹配等复杂问题。本文将详细介绍正则表达式的概念、组成,以及 C#中 ——System.Text.RegularExpressions 命名空间下 Regex 类的使用。

一、正则表达式概述

        正则表达式,英文名为 Regular Expression,是计算机科学领域的重要概念。它借助数学算法,解决计算机程序里的文本检索、匹配等难题。正则表达式语言专注于字符串处理,在众多编程语言中都得到了广泛支持,C# 也不例外。

  1. 检索:通过正则表达式,从字符串中精准获取所需部分。
  2. 匹配:判断给定字符串是否符合正则表达式设定的过滤逻辑。

        可以将正则表达式理解为定义字符串书写规则的工具,比如判断用户输入的密码是否合法,或者邮箱格式是否正确。

二、正则表达式的组成

        正则表达式由普通字符特殊字符(即元字符)构成文字模式,该模式描述了在查找文字主体时待匹配的一个或多个字符串。

三、C# 中操作正则表达式

        在 C# 中,System.Text.RegularExpressions 命名空间下的 Regex 类提供了一系列静态方法和委托,用于操作正则表达式。

1. IsMatch 静态方法

该方法用于判断指定字符串是否与正则表达式匹配,返回值为布尔类型,有三个重载方法:

bool IsMatch(string input, string pattern);
  • 参数
    • input:要搜索匹配项的字符串。
    • pattern:要匹配的正则表达式模式。
  • 返回结果:如果正则表达式找到匹配项,则返回 true;否则,返回 false

 

bool IsMatch(string input, string pattern, RegexOptions options);
  • 参数
    • input:要搜索匹配项的字符串。
    • pattern:要匹配的正则表达式模式。
    • options:枚举值的按位组合,提供匹配选项。
  • 返回结果:如果正则表达式找到匹配项,则返回 true;否则,返回 false

bool IsMatch(string input, string pattern, RegexOptions options, TimeSpan matchTimeout);
  • 参数
    • input:要搜索匹配项的字符串。
    • pattern:要匹配的正则表达式模式。
    • options:枚举值的按位组合,提供匹配选项。
    • matchTimeout:超时间隔,或 System.Text.RegularExpressions.Regex.InfiniteMatchTimeout 指示该方法不应超时。
  • 返回结果:如果正则表达式找到匹配项,则返回 true;否则,返回 false

 

2.RegexOptions 枚举类型

RegexOptions 是一个枚举类型,包含以下常用枚举值:

RegexOptions 枚举值内联标志简单说明
ExplicitCapturen只有定义了命名或编号的组才捕获
IgnoreCasei不区分大小写
IgnorePatternWhitespacex消除模式中的非转义空白并启用由 # 标记的注释
MultiLinem多行模式,修改了 ^ 和 $ 的含义
SingleLines单行模式,与 MultiLine 相对应

        内联标志可针对一组正则表达式,更精细地定义匹配选项。

3. Match 静态方法

        该方法使用指定的匹配选项,在输入字符串中搜索指定正则表达式的第一个匹配项,返回一个包含匹配信息的对象。同样有三个重载方法,参数与 IsMatch 方法相同:

Match Match(string input, string pattern);
Match Match(string input, string pattern, RegexOptions options);
Match Match(string input, string pattern, RegexOptions options, TimeSpan matchTimeout);

        此外,Regex 类中还有一个同名的非静态方法,在处理多个实例时,效率更高。

 

3. Matches 静态方法

        该方法在指定的输入字符串中搜索指定正则表达式的所有匹配项,与 Match 方法不同,它返回所有匹配项。同样有三个重载方法,参数与 Match 方法完全相同:

MatchCollection Matches(string input, string pattern);
MatchCollection Matches(string input, string pattern, RegexOptions options);
MatchCollection Matches(string input, string pattern, RegexOptions options, TimeSpan matchTimeout);

 

4. Replace 方法

        正则表达式主要用于验证、提取、分割和替换字符串,Replace 方法实现了替换功能,有以下四个重载方法:

string Replace(string input, string pattern, string replacement);
  • 参数
    • input:源字符串。
    • pattern:匹配条件。
    • replacement:替换内容,将符合匹配条件 pattern 的内容替换为此内容。

 

string result = Regex.Replace("abc", "ab", "##");
// 结果是##c,把字符串abc中的ab替换成##
string Replace(string input, string pattern, string replacement, RegexOptions options);
  • 参数
    • input:源字符串。
    • pattern:匹配条件。
    • replacement:替换内容。
    • optionsRegexOptions 枚举类型,用于设定匹配选项,如忽略大小写可使用 RegexOptions.IgnoreCase

 

string result = Regex.Replace("ABc", "ab", "##", RegexOptions.IgnoreCase);

        对于复杂的替换需求,比如匹配到多种内容,需要将不同内容替换成不同字符,可使用以下两个方法:

 

string Replace(string input, string pattern, MatchEvaluator evaluator);
  • 参数
    • input:源字符串。
    • pattern:匹配条件。
    • evaluator:一个代理,本质上可理解为一个函数指针,通过代理绑定的函数实现复杂替换。
string Replace(string input, string pattern, MatchEvaluator evaluator, RegexOptions options);
  • 参数
    • input:源字符串。
    • pattern:匹配条件。
    • evaluator:一个代理。
    • optionsRegexOptions 枚举类型,用于设定匹配选项。

 

5. Split 静态方法

        该方法使用正则表达式匹配的位置,将文本拆分为一个字符串数组,有三个重载方法:

string[] Split(string input, string pattern);
string[] Split(string input, string pattern, RegexOptions options);
string[] Split(string input, string pattern, RegexOptions options, TimeSpan matchTimeout);

 

四、正则表达式中的特殊符号与示例

1. @ 符号

        在正则表达式字符串前加上 @ 字符,可防止编译器解析其中的转义字符,使其作为正则表达式的语法(元字符)存在。

string s = @"www.baidu.com \n lkjsdflkj";

2. 定位元字符

字符说明
\b匹配单词的开始或结束
\B匹配非单词的开始或结束
^匹配必须出现在字符串的开头或行的开头
$匹配必须出现在以下位置:字符串结尾、字符串结尾处的 \n 之前或行的结尾
\A指定匹配必须出现在字符串的开头(忽略 Multiline 选项)
\z指定匹配必须出现在字符串的结尾(忽略 Multiline 选项)
\z指定匹配必须出现在字符串的结尾或字符串结尾处的 \n 之前(忽略 Multiline 选项)
\G指定匹配必须出现在上一个匹配结束的地方,与 Match.NextMatch() 一起使用时,确保所有匹配都是连续的
定位元字符示例
// 示例一:匹配开始 ^
string str = "I am Blue cat";
Console.WriteLine(Regex.Replace(str, "^", "准备开始:"));

// 示例二:匹配结束 $
string str2 = "I am Blue cat";
Console.WriteLine(Regex.Replace(str2, "$", " 结束了!"));

 

3. 基本语法元字符

字符说明
.匹配除换行符以外的任意字符
\w匹配字母、数字、下划线、汉字 (指大小写字母、0 - 9 的数字、下划线_)
\W\w 的补集 (除 “大小写字母、0 - 9 的数字、下划线_” 之外)
\s匹配任意空白符 (包括换行符 \n、回车符 \r、制表符 \t、垂直制表符 \v、换页符 \f)
\S\s 的补集 (除 \s 定义的字符之外)
\d匹配数字 (0 - 9 数字)
\D表示 \d 的补集 (除 0 - 9 数字之外)

        在正则表达式中,\ 是转义字符,* 是元字符。若要表示 \.* 字符,需使用 \\\.\*

基本语法元字符示例
// 示例一:校验只允许输入数字
string strCheckNum1 = "23423423a3", strCheckNum2 = "324234";
Console.WriteLine("匹配字符串" + strCheckNum1 + "是否为数字:" + Regex.IsMatch(strCheckNum1, @"^\d*$"));
Console.WriteLine("匹配字符串" + strCheckNum2 + "是否为数字:" + Regex.IsMatch(strCheckNum2, @"^\d*$"));

// 示例二:校验只允许输入除大小写字母、0 - 9的数字、下划线_以外的任何字符
string strCheckStr1 = "abcds_a", strCheckStr2 = "**&&((((2", strCheckStr3 = "**&&((((";
string regexStr = @"^\W*$";
Console.WriteLine("匹配字符串" + strCheckStr1 + "是否为除大小写字母、0 - 9的数字、下划线_以外的任何字符:" + Regex.IsMatch(strCheckStr1, regexStr));
Console.WriteLine("匹配字符串" + strCheckStr2 + "是否为除大小写字母、0 - 9的数字、下划线_以外的任何字符:" + Regex.IsMatch(strCheckStr2, regexStr));
Console.WriteLine("匹配字符串" + strCheckStr3 + "是否为除大小写字母、0 - 9的数字、下划线_以外的任何字符:" + Regex.IsMatch(strCheckStr3, regexStr));

4. 反义字符

字符说明
\W\w 的补集 (除 “大小写字母、0 - 9 的数字、下划线_” 之外)
\S\s 的补集 (除 \s 定义的字符之外)
\D表示 \d 的补集 (除 0 - 9 数字之外)
\B匹配不是单词开头或结束的位置
[ab]匹配中括号中的字符
[a - c]匹配 a 字符到 c 字符之间的字符
[^x]匹配除了 x 以外的任意字符
[^adwz]匹配除了 adwz 这几个字符以外的任意字符
反义字符示例
// 示例:查找除ahou这之外的所有字符
string strFind1 = "I am a Cat!", strFind2 = "My Name's Blue cat!";
Console.WriteLine("除ahou这之外的所有字符,原字符为:" + strFind1 + "替换后:" + Regex.Replace(strFind1, @"[^ahou]", "*"));
Console.WriteLine("除ahou这之外的所有字符,原字符为:" + strFind2 + "替换后:" + Regex.Replace(strFind2, @"[^ahou]", "*"));

5. 重复描述字符

字符说明
{n}匹配前面的字符 n 次
{n,}匹配前面的字符 n 次或多于 n 次
{n,m}匹配前面的字符 n 到 m 次
?重复零次或一次
+重复一次或更多次
*重复零次或更多次
重复描述字符示例
// 示例:校验输入内容是否为合法QQ号(备注:QQ号为5 - 12位数字)
string isQq1 = "1233", isQq2 = "a1233", isQq3 = "0123456789123", isQq4 = "556878544";
string regexQq = @"^\d{5,12}$";
Console.WriteLine(isQq1 + "是否为合法QQ号(5 - 12位数字):" + Regex.IsMatch(isQq1, regexQq));
Console.WriteLine(isQq2 + "是否为合法QQ号(5 - 12位数字):" + Regex.IsMatch(isQq2, regexQq));
Console.WriteLine(isQq3 + "是否为合法QQ号(5 - 12位数字):" + Regex.IsMatch(isQq3, regexQq));
Console.WriteLine(isQq4 + "是否为合法QQ号(5 - 12位数字):" + Regex.IsMatch(isQq4, regexQq));

6. 择一匹配

| 字符用于将两个匹配条件进行逻辑 “或”(Or)运算。

择一匹配示例
// 示例一:查找数字或字母
string findStr1 = "ad(d3)-df";
string regexFindStr = @"[a-z]|\d";
string newStrFind = String.Empty;
MatchCollection newStr = Regex.Matches(findStr1, regexFindStr);
newStr.Cast<Match>().Select(m => m.Value).ToList<string>().ForEach(i => newStrFind += i);
Console.WriteLine(findStr1 + "中的字母和数字组成的新字符串为:" + newStrFind);

// 示例二:将人名输出("zhangsan;lisi,wangwu.zhaoliu")
string strSplit = "zhangsan;lisi,wangwu.zhaoliu";
string regexSplitstr = @"[;]|[,]|[.]";
Regex.Split(strSplit, regexSplitstr).ToList().ForEach(i => Console.WriteLine(i));

7. 对正则表达式分组 ()

使用小括号来指定子表达式(也叫做分组)。

分组示例
// 示例一:重复单字符和重复分组字符
Console.WriteLine("请输入一个任意字符串,测试分组:");
string inputStr = Console.ReadLine();
string strGroup1 = @"a{2}";
Console.WriteLine("单字符重复2两次替换为22,结果为:" + Regex.Replace(inputStr, strGroup1, "22"));
// 重复多个字符 使用(abcd){n}进行分组限定
string strGroup2 = @"(ab\w{2}){2}";
Console.WriteLine("分组字符重复2两次替换为5555,结果为:" + Regex.Replace(inputStr, strGroup2, "5555"));

// 示例二:校验IP4地址(如:192.168.1.4,为四段,每段最多三位,每段最大数字为255,并且第一位不能为0)
string regexStrIp4 = @"^(((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?))$";
Console.WriteLine("请输入一个IP4地址:");
string inputStrIp4 = Console.ReadLine();
Console.WriteLine(inputStrIp4 + " 是否为合法的IP4地址:" + Regex.IsMatch(inputStrIp4, regexStrIp4));
Console.WriteLine("请输入一个IP4地址:");
string inputStrIp4Second = Console.ReadLine();
Console.WriteLine(inputStrIp4 + " 是否为合法的IP4地址:" + Regex.IsMatch(inputStrIp4Second, regexStrIp4));

五·结语

        通过对正则表达式的深入学习,我们能够在 C# 编程中,更高效地处理字符串相关的复杂问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值