0612_正则表达式
正则表达式
C# 中的正则表达式是通过 System.Text.RegularExpressions
命名空间下的 Regex
类来实现的。正则表达式是一种强大的文本处理工具,用于搜索、匹配、替换和验证字符串中的模式。。通俗的讲就是按照某种规则去匹配符合条件的字符串
正则表达式的用途:
- 表单输入验证。
- 搜索和替换。
- 过滤大量文本文件(如日志)中的信息。
- 读取配置文件。
- 网页抓取。
- 处理具有一致语法的文本文件,
正则初识
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;namespace _01_正则初识
{internal class Program{static void Main(string[] args){string s = "24379hfduishi都343是hihd34313413fuisdhui34";//输出所有的数字for (int i = 0; i < s.Length; i++){if (s[i] >= '0' && s[i]<='9'){Console.WriteLine(s[i]);}}Regex.Matches(s, @"\d");foreach (Match match in Regex.Matches(s, @"\d")){Console.WriteLine(match);}}}
}
创建正则
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;namespace _02_创建正则
{internal class Program{static void Main(string[] args){
//@""创建的字符串 会忽略转义字符,并保留原来的格式,写什么就是什么
//正则表达式就是一个字符串,只是用字符串表示一种匹配模式, 比如: \d 匹配数字的模式 \w匹配单词的模式...
//因为在正则中需要使用\ xxx 因此不能使用普通的字符串创建方式,因为普通的字符串创建方式, 会解析 \//1.创建一个正则表达式
//\d 子表达式表示一种规则(匹配所有的数字) 一个正则可以由多个子表达式组成Regex reg1 = new Regex(@"\d");string string1 = "123abcd368a7934acababc";
//***abcd***a****acababc//2. 正则表达式对象的Replace方法,用于替换字符,返回替换之后的字符串
Console.WriteLine(reg1.Replace(string1, "*"));//********hkfhskdhi收到复议***//正则表达式包含两个子表达式,分别为a和b,表示匹配字符a和字符b 并且必须相邻
Regex reg2 = new Regex(@"ab");Console.WriteLine(reg2.Replace(string1, "*"));
//123*cd368a7934ac**c//正则表达式中的普通字符,写什么就是什么,有些字符比较特殊,需要使用\进行转义
//比如: \ . * [] () {}....string string2 = "这是一个杠\\,这是一个点. 这是一个星号*";
Console.WriteLine("源字符串" + string2);
//源字符串这是一个杠\,这是一个点. 这是一个星号*Regex reg3 = new Regex(@"\\");
Console.WriteLine(reg3.Replace(string2, "%"));
//这是一个杠%,这是一个点. 这是一个星号*Regex reg4 = new Regex(@"\.");
Console.WriteLine(reg4.Replace(string2, "%"));//这是一个杠\,这是一个点% 这是一个星号*Regex reg5 = new Regex(@"\*");
Console.WriteLine(reg5.Replace(string2, "%"));//这是一个杠\,这是一个点. 这是一个星号%string string3 = "123\n新的一行\t一个tab,一个提示音\a";Console.WriteLine("源字符串+==" + string3);
//源字符串 +== 123
//新的一行 一个tab, 一个提示音Regex reg6 = new Regex(@"\a");
Console.WriteLine(reg6.Replace(string3, "%"));
//123
//新的一行 一个tab, 一个提示音%
Regex reg7 = new Regex(@"\t");
Console.WriteLine(reg7.Replace(string3, "%"));
//123
//新的一行 % 一个tab,一个提示音
Regex reg8 = new Regex(@"\n");
Console.WriteLine(reg8.Replace(string3, "%"));
//123%新的一行 一个tab,一个提示音//string4 使用的是@"" 创建的 其中\n \t 不表示 换行和索引 因此正则中 \n\t也匹配不到
//正则中需要使用\\n \\t 进行转义 表示要匹配的是真正的\n \t 而不是换行 和缩进
string string4 = @"123\n新的一行\t一个tab,一个提示音\a";//普通字符串中 \a 匹配字符串中的\a
// \n匹配字符串中的\n//@"" 创建的字符串 \\n 匹配的是字符串中的\nRegex reg9 = new Regex(@"\\n");
Console.WriteLine(reg9.Replace(string4, "%"));//123%新的一行\t一个tab,一个提示音\a}}
}
字符类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;namespace _03_字符类
{internal class Program{static void Main(string[] args){//上个课件中的子表达式 一个字符就表示匹配固定的那一个字符
//字符类 一组字符中任意一个字符的匹配string s1 = "34343127941374123ahfkj344793784jfskhad324";Regex reg1 = new Regex(@"12");
Console.WriteLine(reg1.Replace(s1, "*"));//34343*7941374*3ahfkj344793784jfskhad324//[12] 匹配[] 中所有字符中的任意一个
Regex reg2 = new Regex(@"[12s]");
Console.WriteLine(reg2.Replace(s1, "*"));//34343**794*374**3ahfkj344793784jf*khad3*4//[^12s] 匹配[] 除了12之外所有的字符
Regex reg3 = new Regex(@"[^abs]");
Console.WriteLine(reg3.Replace(s1, "*"));//*****************a***************s**a****string s2 = "eryAaiewyuHcIJb中KsdfhisduhGUGYURFtuytUF";//[a-c] 匹配a到c之间所有的小写字母
Regex reg4 = new Regex(@"[a-z]");
Console.WriteLine(reg4.Replace(s2, "*"));//***A******H*IJ*中K*********GUGYURF****UF
//[C-J] 匹配C-J之间所有得大写字母//[C-Jc-j] 匹配c-j之间大写和小写字母
//[A-Z] 匹配所有得大写字母
//[a-z] 匹配所有得小写字母
//[A-Za-z] 匹配所有的字母
Regex reg5 = new Regex(@"[C-Jc-j]");
Console.WriteLine(reg5.Replace(s2, "*"));//*ryAa**wyu****b中Ks****s*u**U*YUR*tuytU*//[\u4e00-\u9fa5] 匹配中文字符
Regex reg6 = new Regex(@"[\u4e00-\u9fa5]");
Console.WriteLine(reg6.Replace(s2, "*"));//eryAaiewyuHcIJb*KsdfhisduhGUGYURFtuytUFstring s3 = "123abc中文\n&)(^$换行测试";//. 除了 \n 换行之外 任意字符
Regex reg7 = new Regex(@"\W");
//\w 匹配任何单词字符 (除了一些特殊符号)
//\W 匹配非任何单词字符 (匹配一些特殊符号)
//\d 匹配数字
//\D 匹配非数字
//\s 空白字符
//\S 非空白字符
Console.WriteLine(reg7.Replace(s3, "*"));
//123abc中文******换行测试}}
}
限定符
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;namespace _04_限定符
{internal class Program{static void Main(string[] args){string s1 = "a aa aaa b bb abbb aaaa";Regex regex1 = new Regex(@"aaa");
Console.WriteLine(regex1.Replace(s1, "*"));//a aa * b bb abbb *a//使用限定符控制子表达式出现的次数Regex regex2 = new Regex(@"a{4}");
Console.WriteLine(regex2.Replace(s1, "*"));//a aa aaa b bb abbb *string s2 = "a aa aaa b bb bbb aaa ab ac";//[ab]{2} a或者b出现两次 aa bb ab ba
Regex regex3 = new Regex(@"[ab]{2}");
Console.WriteLine(regex3.Replace(s2, "*"));//a * *a b * *b *a * ac//@"[a]{2,} 前面一个子表达式至少出现2次 最多不限制
//@"[a]{2,5}"前面一个子表达式至少出现2次 最多出现5次
Regex regex4 = new Regex(@"[a]{2,5}");
Console.WriteLine(regex4.Replace(s2, "*"));//a * * b bb bbb * ab ac// @\d{3,5}
// * 前一个子表达式至少出现0次 最多不限制{0,}
// + 前一个子表达式至少出现1次 最多不限制{1,}
// ? 前一个子表达式至少出现0次 最多1次{0,1}//贪婪模式//默认正则表达式 以贪婪模式进行查询 尽量多的匹配满足条件的字符
string s4 = "1 12 123 1234 12345 123456";
Regex regex5 = new Regex(@"\d{3,}");
Console.WriteLine(regex5.Replace(s4, "*"));//1 12 * * * *//我们可以在两次的后面加上一个? 修改这个两次为非贪婪模式,会尽可能少的匹配字符
Regex regex6 = new Regex(@"\d{3,}?");
Console.WriteLine(regex6.Replace(s4, "*"));//1 12 * *4 *45 **}}
}
定位点
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;namespace _05_定位点
{internal class Program{static void Main(string[] args){string s = "1ab1fhi";//^ 写在正则表达式的最前面, 表示 以"后一个表达式"开头 或者为行的开头(开启正则表达式的多行匹配模式)Regex regex = new Regex(@"^\d");Console.WriteLine(regex.IsMatch(s));//Trues = "a1bc12";//必须以三个小写字母开头regex = new Regex(@"^[a-z]{3}");Console.WriteLine(regex.Replace(s,"*"));//a1bc12// $ 写在正则表达式的最后面, 表示 以"前一个表达式"结尾 或者为行的结尾(开启正则表达式的多行匹配模式)s = "abcb1c";regex = new Regex(@"[a-z]{3}$");Console.WriteLine(regex.Replace(s, "*"));//abcb1c// ^ 和$ 默认只匹配单行的开头和结尾s= "abc\nabc";//RegexOptions.Multiline 可以在创建表达式的时候 指定表达式为多行匹配模式,匹配任意一行的开头和结尾regex = new Regex(@"^a",RegexOptions.Multiline);Console.WriteLine(regex.Replace(s, "*"));//*bc//*bcregex = new Regex(@"c$", RegexOptions.Multiline);Console.WriteLine(regex.Replace(s, "*"));//ab*//ab*s = "bbc\nbabc";//\A 必须出现在字符串开头的位置 多行匹配也不会查询到其他行regex = new Regex(@"\Ab", RegexOptions.Multiline);Console.WriteLine(regex.Replace(s, "*"));//*bc//babc// \Z 必须出现在字符串的结尾位置 或者和最后的\n之前,多行匹配也不会查询到其他行regex = new Regex(@"c\Z", RegexOptions.Multiline);Console.WriteLine(regex.Replace(s, "*"));//bbc//bab*}}
}
分组
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;namespace _06_分组
{internal class Program{static void Main(string[] args){//分组: 描述正则表达式的子表达式 通过用于捕获输入字符串的字符串string s = "aa1a111 bb cc a b c c ab bc cccc sssss";// 在正则中() 将某些子表达式括起来,将他们分为一组,组的编号 从1开始// 在正则中 使用 \编号 引用分组匹配到的字符Regex regex = new Regex(@"([a-z]){5}");Console.WriteLine(regex.Replace(s, "*"));//aa1a111 bb cc a b c c ab bc cccc *//(\w)([123])\1\2{3}===> (\w)([123])(\w)\([123]){3}regex = new Regex(@"(\w)([123])\1\2{3}");Console.WriteLine(regex.Replace(s, "*"));//a* bb cc a b c c ab bc cccc sssss}}
}
正则查询
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;namespace _07_正则查询
{internal class Program{static void Main(string[] args){string s = "abc123abc234";Regex regex = new Regex(@"^\d");//正则对象的Match方法,用于从指定的字符串中,查询满足条件的第一个匹配项//从字符串中查询第一个满足正则表达式的规则的 字符串Match m= regex.Match(s);Console.WriteLine(m.Value);//null//Matches 用于从字符串中查询所有的满足正则表达式的规则的字符串MatchCollection ms = regex.Matches(s);foreach (Match item in ms){Console.WriteLine(item.Value);}Console.WriteLine(ms.Count);//0//判断 字符串是否符合正则表达式的验证规则//符合规则就返回true 不符合 返回falsebool b = regex.IsMatch(s);//falseConsole.WriteLine(b);//falseregex =new Regex(@"\d");foreach (string item in regex.Split(ss)){Console.WriteLine(item);//abc}}}
}
正则查询练习
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;namespace _08_正则练习
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){//Regex regex = new Regex(@"^1[3-9]\d{9}$");bool b= regex.IsMatch(textBox1.Text);if (b) {MessageBox.Show("合法");///}else{MessageBox.Show("不合法");}}}
}
零宽断言
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;namespace _09_零宽断言
{internal class Program{static void Main(string[] args){//零宽断言: 不占用宽度的匹配判断string s = "ab ac ad bac bab";//表达式A(?=表达式B)" 需要的是表达式A 但是后面必须满足表达式B//@"a(?=b)" 需要a 但是这个a后面必须有b 没有b的不要Regex regex = new Regex(@"a(?=b)");Console.WriteLine(regex.Replace(s,"*"));//*b ac ad bac b*b//表达式A(?! 表达式B) 需要的是表达式A 但是后面必须不满足表达式B//@"a(?!=b)" 需要a 但是这个a后面不能有b 有b的不要regex = new Regex(@"a(?!b)");Console.WriteLine(regex.Replace(s, "*"));//ab *c *d b*c bab// 需要 b 但是前面必须是a//需要的是b 但是不是所有的都要 要的是前面有a的 bregex = new Regex(@"(?<=a)b");Console.WriteLine(regex.Replace(s, "*"));//a* ac ad bac ba*//需要 b 但是前面不能是aregex = new Regex(@"(?<!a)b");Console.WriteLine(regex.Replace(s, "*"));//ab ac ad *ac *ab}}
}
备用构造
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;namespace _10_备用构造
{internal class Program{static void Main(string[] args){// 可以使用 () 和 | 进行多个表达式之间的 或者 关系表示//(aa|bb|cc) 表示 aa或者bb 或者cc 和[]的区别在于 []表示多个字符中的某个字符,(|) 可以表示多个string s = "ab ac abc acd";Regex regex = new Regex(@"(ab|ac)");Console.WriteLine(regex.Replace(s,"*"));//* * *c *d//Replace 替换字符串 也可以使用正则分组中捕获到的内容//+ 表示一个或者多个 a+b 捕获ab aab aaab 但是不匹配bregex = new Regex(@"\b(\w+)(\s)(\w+)\b");//使用$n 表示第n个分组捕获到的内容Console.WriteLine(regex.Replace("one two", "第三组内容为$3,第二组内容为$2,第一组内容为$1"));//第三组内容为two,第二组内容为 ,第一组内容为one}}
}
替换
练习
- 验证一个车牌是否符合规范
- 接收用户输入一个邮箱, 正则验证邮箱是否正确
- 接收用户输入一个 xxxx-xx-xx格式的字符,判断是否为有效的日期(不考虑2月和平闰年)
https://blog.csdn.net/fd2025/article/details/125326832
示例
-
手机号码的校验
phoneReg = @"^[1][3456789][0-9]{9}$"
-
身份证的校验
sfzReg = @"^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$"
-
邮箱的校验
emailReg = @"^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$"
-
URL的校验
urlReg = @"^((https?|ftp|file):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$"
-
IPv4的校验
ipv4Reg = @"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
-
16进制颜色的校验
color16Reg = @"^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$"
-
日期 YYYY-MM-DD
dateReg = @"^\d{4}(\-)\d{1,2}\1\d{1,2}$"
-
日期 YYYY-MM-DD hh:mm:ss
dateReg = @"^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$"
-
整数的校验
intReg = @"^[-+]?\d*$"
-
小数的校验
floatReg = @"^[-\+]?\d+(\.\d+)?$"
-
保留3位小数(其中3可以换成任意位数)
floatReg = @"^([1-9]+[\d]*(.[0-9]{1,3})?)$"
-
邮政编号的校验
postalNoReg = @"^\d{6}$"
-
QQ号的校验
qqReg = @"^[1-9][0-9]{4,10}$"
-
微信号的校验(说明:6至20位,以字母开头,字母,数字,减号,下划线)
wxReg = @"^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$"
-
车牌号的校验
carNoReg = @"^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$"
-
只含字母的字符串
letterReg = @"^[a-zA-Z]+$"
-
包含中文的字符串
cnReg = @"[\u4E00-\u9FA5]"
-
密码强度的校验
passwordReg = @"(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9]).{8,30}"
-
字符串长度n的校验
lengthReg = @"^.{n}$"
-
文件拓展名的校验
filenameReg = @"(.jpg|.png|.txt)$"
-
匹配img和src
imgReg = @"<img.*?src=[\"|\']?(.*?)[\"|\']?\s.*?>"