C#正则表达式:5个自定义函数,让复杂查询从“难如登天“到“信手拈来“!
🔥关注墨瑾轩,带你探索编程的奥秘!🚀
🔥超萌技术攻略,轻松晋级编程高手🚀
🔥技术宝库已备好,就等你来挖掘🚀
🔥订阅墨瑾轩,智趣学习不孤单🚀
🔥即刻启航,编程之旅更有趣🚀


第一步:理解正则表达式基础——别被"正则"两个字吓到
正则表达式是匹配输入文本的模式,C#通过Regex类实现。以下是基础用法:
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "Hello, world! 123";
string pattern = @"\d+"; // 匹配一个或多个数字
// 检查匹配
bool isMatch = Regex.IsMatch(input, pattern);
Console.WriteLine($"是否匹配: {isMatch}"); // 输出: 是否匹配: True
// 获取第一个匹配
Match match = Regex.Match(input, pattern);
Console.WriteLine($"第一个匹配: {match.Value}"); // 输出: 第一个匹配: 123
// 获取所有匹配
MatchCollection matches = Regex.Matches(input, pattern);
Console.WriteLine("所有匹配:");
foreach (Match m in matches)
{
Console.WriteLine($"- {m.Value}");
}
// 输出:
// - 123
}
}
注释:Regex.IsMatch检查字符串是否匹配模式,Regex.Match返回第一个匹配项,Regex.Matches返回所有匹配项。
精准吐槽:正则表达式就像一把瑞士军刀,看起来复杂,但用对了,能解决90%的文本处理问题。用错了,就只能当废铁扔了。
血泪教训:我曾经在项目中把正则表达式写得过于复杂,导致代码难以维护,后来不得不重构,花了整整两天时间。正则表达式不是越复杂越好,而是越简洁越好。
第二步:自定义替换函数——让复杂替换"一招搞定"
Regex.Replace可以接受MatchEvaluator委托,实现复杂的替换逻辑:
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string text = "价格:100,折扣后:80;价格:200,折扣后:150";
string pattern = @"\d+"; // 匹配数字
// 使用回调函数将价格增加10%
string result = Regex.Replace(text, pattern, match =>
{
if (int.TryParse(match.Value, out int price))
{
return (price * 1.1).ToString("0.00");
}
return match.Value;
});
Console.WriteLine(result);
// 输出:价格:110.00,折扣后:88.00;价格:220.00,折扣后:165.00
}
}
注释:MatchEvaluator委托允许我们在替换时执行自定义逻辑,比如根据匹配内容进行计算。
技术冷幽默:Regex.Replace加MatchEvaluator,就像给正则表达式装了个"智能大脑",不再只是简单的字符串替换,而是能根据内容做决策。
血泪教训:在一次项目中,我尝试用正则表达式直接处理复杂的价格计算,结果写得一团糟。后来改用MatchEvaluator,代码清晰多了,性能也提升了20%。
第三步:命名分组与条件替换——让复杂查询"一目了然""
命名分组可以提高正则表达式的可读性,结合条件替换可以实现更灵活的处理:
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string text = "张三:男,25;李四:女,30;王五:男,35";
string pattern = @"(?<name>\w+):(?<gender>男|女),(?<age>\d+)";
// 根据性别添加不同的前缀
string result = Regex.Replace(text, pattern, match =>
{
string gender = match.Groups["gender"].Value;
string prefix = gender == "男" ? "先生" : "女士";
return $"{match.Groups["name"].Value}{prefix}({match.Groups["age"].Value}岁)";
});
Console.WriteLine(result);
// 输出:张三先生(25岁);李四女士(30岁);王五先生(35岁)
}
}
注释:(?<name>\w+)是命名分组,match.Groups["name"]可以获取分组捕获的内容。命名分组让正则表达式更易读,也方便在替换逻辑中引用。
精准吐槽:命名分组就像给正则表达式的每个部分都贴上标签,你不再需要记住$1、$2这些数字,而是直接用name、gender这样的名字,清晰明了。
血泪教训:我曾经在项目中使用了数字分组,结果几个月后自己都看不懂代码了。后来改用命名分组,不仅自己看得懂,还让团队其他成员更容易维护。
第四步:保留分隔符的拆分——让复杂文本"一分为二""
通过分组可以在拆分结果中保留分隔符:
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string text = "第一章 介绍\n1.1 背景\n1.2 目的\n第二章 方法\n2.1 步骤";
string pattern = @"(\d+章)|(d+.d+)";
string[] parts = Regex.Split(text, pattern);
Console.WriteLine("拆分结果:");
foreach (string part in parts)
{
if (!string.IsNullOrEmpty(part))
{
Console.WriteLine($"[{part}]");
}
}
// 输出:
// [第一章]
// 介绍
//
// [1.1]
// 背景
//
// [1.2]
// 目的
//
// [第二章]
// 方法
//
// [2.1]
// 步骤
}
}
注释:(\d+章)|(d+.d+)是分组,Regex.Split会保留这些分组,让拆分后的结果包含分隔符。
技术梗:Regex.Split加分组,就像给文本装了个"智能分隔器",不仅能把文本分开,还能把分隔符也保留下来,方便后续处理。
血泪教训:在一次项目中,我需要处理类似"1.1 背景"这样的章节标题,但普通的Split会把"1.1"也切掉,导致数据丢失。后来用了带分组的Split,完美解决了问题。
第五步:处理复杂条件匹配——让正则表达式"聪明"起来"
正则表达式可以处理复杂的条件匹配,但需要合理设计模式:
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string text = "电话:1234567,手机:13888888888,固话:12345678,无效号码:123456";
// 匹配有效电话号码:7-8位固话或11位手机号
string pattern = @"(^\d{7,8}$)|(1\d{10})";
// 匹配有效号码
MatchCollection validMatches = Regex.Matches(text, pattern);
Console.WriteLine("有效号码:");
foreach (Match match in validMatches)
{
Console.WriteLine($"- {match.Value}");
}
// 输出:
// 有效号码:
// - 1234567
// - 13888888888
// - 12345678
// 匹配无效号码
string invalidPattern = @"(?<!\d)(\d{6})";
MatchCollection invalidMatches = Regex.Matches(text, invalidPattern);
Console.WriteLine("\n无效号码:");
foreach (Match match in invalidMatches)
{
Console.WriteLine($"- {match.Value}");
}
// 输出:
// 无效号码:
// - 123456
}
}
注释:(?<!\d)是负向否定环视,表示前面不能有数字。(\d{6})匹配6位数字,但前面不能有数字,所以匹配"123456"而不是"1234567"。
精准吐槽:正则表达式中的环视(Lookaround)就像给正则表达式装了个"眼睛",能看前后文,判断是否符合条件,让匹配更精准。
血泪教训:我曾经在项目中试图用正则表达式匹配电话号码,但忽略了号码前后的上下文,导致匹配了不该匹配的内容。后来用了环视,问题迎刃而解。
更多推荐



所有评论(0)