正则表达式

一、正则表达式概述、元字符及含义

正则表达式是用来处理字符串的,针对字符串进行较为复杂的处理。

正则表达式就是由普通字符以及特殊字符(称为元字符)组成的"规则字符串",这个"规则字符串"用来表达对字符串的一种过滤逻辑 ,也即是说正则表达式用来描述字符串的特征,用于字符串匹配字符串提取字符串替换

类似于通配符,比如*.jpg , ?ab, 这里 *、?是通配符,类似于元字符。又如like '张%' 。

通配符

1、. 除\n(换行)以外的任意的单个字符。

csharp 复制代码
a.b		表示ab之间有一个字符,且必须有一个,除了换行符

2、[] 字符组:[] 表示在字符组中罗列出来的字符中,任意取1一个。

csharp 复制代码
a[xyz]b 表示在xyz三个中必须取1个,如axb、ayb、azb 都行
a[a-z]b 表示小写a到z之间必须取1个,如awb、azb、aab都行
a[a-zABXYZ]b 表示小写a到z或者ABXYZ之间必须取1个,如aAb
a[a-zA-Z0-9一二三]b 表示小写a到z、大写A到Z、0到9、一、二、三之间取1个

注意1: 		-出现在[]第一个不表示范围,如
a[-a-zX]b		表示在-、小写a到z和X必须取1个

注意2:			.出现在字符组中表示一个普通的.,并不是一个元字符。因此,a.b与a[.]b意思不同
a[.xyz]b		表示在.、x、y、z中必须取1个

注意3:a\.b		\.表示把.转义了,就表示1个普通字符,不是元字符了 a.b

3、|表示"或"的意思。"或"的优先级最低。

csharp 复制代码
a(x|y)b  表示a和b之间要么是x,要么是y。axb ayb 
z|food  表示匹配z或者匹配food
(z|f)ood  表示zood或food,通过()改变优先级
()表示 "改变优先级"或者表示"提取组"。

4、[0-9]:表示0到9之间的数字任意取1个。

csharp 复制代码
[0-9]可以用[\d]表示,并不完全等价,主要在于默认情况下全角数字匹配\d,但是不匹配[0-9]。
\d	表示0到9之间的数字 
\D 	除了0到9之间的数字字符的其他字符,也即是非数字字符
\w	表示匹配字母或数字或下划线或汉字,即表示能组成单词的字符,即表示[a-zA-Z0-9],汉字是指在Unicode模式下才可以有的。
\W	除了[a-zA-Z0-9_]外的其他字符
\s   表示所有不可见字符  如:空格\r\n(\r回车符、\n换行符)。
\S   表示所有可见字符
	因此,以下几个都可以表示任意单个字符:[\s\S]、[\d\D]、[\w\W].

限定符及其含义

1、a.*b *表示限定前面的表达式或元素出现0次或者多次。这里只能表示前面的.可出现0次或者多次,如果要表示前面的a. 出现0次或者多次,则要把a.括起来,即是(a.)*b。

2、a.+b +表示上一个元素出现一次或多次,至少得出现一次。

3、a.?b ?表示上一个元素可以出现0次或1次,?另一个意思是终止贪婪模式。

4、

(1){n}表示匹配上一个元素恰好n次,比如[0-9]{8}------表示0-9的任意数字出现8次

(2){n,}匹配上一个元素至少n次,比如[0,9]{4,}------表示0-9的任意数字至少出现4次

(3){n,m}匹配上一个元素至少n次,但不多于m次,比如[0-9]{4,9}------表示0-9的任意数字至少出现4次,最多出现9次

5、^hl ^表示开头,这个表示以hl开头(注意:出现在[]里不表示开头的意思,表示非的意思)

6、oo$ ------$表示结尾,这个就表示以oo结尾的字符串 例如Zoo、yahoo、too

7、\b------匹配单词边界

验证数字、邮政编码、手机号等常见数字验证

在C#中,要使用正则表达式类,主要用RegEX类,并需要引入命名空间

csharp 复制代码
using System.Text.RegularExpressions;
RegEx类常用的方法------IsMatch
语法格式如下
public static bool IsMatch(string input, string pattern);
input:要搜索匹配项的字符串
pattern:要匹配的正则表达式模式
返回值:如果正则表达式找到匹配项,则为true,否则为false

验证输入的字符是否为数字

csharp 复制代码
  Console.WriteLine("请输入数字字符串:");
  string num = Console.ReadLine();
  Console.WriteLine(Regex.IsMatch(num,"^[0-9]+$"));
  Console.ReadKey();

^:以[0-9]+$  开头
$:以[0-9]+   结尾
+:表示[0-9]元素出现一次或多次
[0-9]:表示0到9之间的数字任意取一个
注意:.Net默认使用的是Unicode匹配模式

验证是否是合法的手机号

csharp 复制代码
  Console.WriteLine("请输入手机号:");
  string num = Console.ReadLine();
  Console.WriteLine(Regex.IsMatch(num, @"^\d{11}$"));
  //@为取消\的转义,当然也可以写成"^\\d{11}$",即写两个\
  //如果不加^$,则只要输入的字符串含有11个连续数字就可以的
  Console.ReadKey();

验证给定的字符串是否为一个合法的邮政编码

csharp 复制代码
   Console.WriteLine("请输入一个字符串:");
   string str = Console.ReadLine();
  //bool b = Regex.IsMatch(str, "[0-9]{6}");
 //注意,要想完全匹配,必须要加^和$。否者只要字符串中有一部分与给定的正则表达式匹配,就返回true了。
   bool b = Regex.IsMatch(str, "^[0-9]{6}$");
   Console.WriteLine("给定的字符串是一个合法的邮政编码吗?{0}",b);
   Console.ReadKey();

验证身份证号、电话号码、合法日期等数字验证

判断一个字符串是不是身份证号码。
csharp 复制代码
    while (true)
            {
                Console.WriteLine("输入身份证号:");
                string idNo = Console.ReadLine();
                Console.WriteLine(Regex.IsMatch(idNo, @"(^[1-9][0-9]{14})$|(^[1-9][0-9]{16}[0-9Xx]$)"));
                //其中[1-9]为一个数字,[0-9]{16}为十六个数字 [0-9Xx]为一个数字或字母
            }
判断字符串是否为正确的国内电话号码,不考虑分机
csharp 复制代码
  while (true)
            {
                //{n}表示匹配上一个元素恰好n次
                //{n,}表示匹配上一个元素至少n次
                //{n,m}匹配上一个元素至少n次,但不多于m次
                Console.WriteLine("请输入电话号码:");
                string number = Console.ReadLine();
                //\d{3,4}-?\d{7,8}这个也包括\d{11}这种情况
                //\d{5}
                bool b = Regex.IsMatch(number, @"^(\d{3,4}-?\d{7,8}|\d{5})$");
                //@的作用:当在正则表达式之前放置@时,表示后面的字符串将字母意义来解析,也就是所有字符都将视为普通文本,不进行任何转义处理。
                //?的作用:?表示上一个元素可以出现0次或者1次
                Console.WriteLine(b);
            }
判断是否是合法的日期格式,如"2022-2-22"。
csharp 复制代码
  while (true)
    {
      Console.WriteLine("输入日期:");
      string date = Console.ReadLine();
       //bool b = Regex.IsMatch(date, @"^[0-9]{4}-[0-9]{2}-[0-9]{2}$");
       //限制月份只能是1-12月
       //0[1-9] 01-09
       //1[0-2] 10-12
       //问号表示前面的元素可以出现0次或1次
       //bool b = Regex.IsMatch(date, @"^[0-9]{4}-(0?[1-9]|1[0-2])-[0-9]{2}$");
       //限制日期只能在1-31之间
       bool b = Regex.IsMatch(date, @"^[0-9]{4}-(0?[1-9]|1[0,2])-((0?[1-9])|([1-2][0-9])|30|31)$");
        Console.WriteLine(b);
      }
验证一个数字表达式是否为两位小数。
csharp 复制代码
  Console.WriteLine("输入一个数字表达式:");
  string strnum = Console.ReadLine();
  //+表示上一个元素出现一次或多次
  //{n}表示匹配上一个元素恰好n次
  bool b = Regex.IsMatch(strnum, @"^[0-9]+(\.[0-9]{2})$");
  Console.WriteLine(b);

Email、URL、IP等网络验证应用

验证是否为合法的邮政地址

csharp 复制代码
//xu-zhaoxing@163.com
//447.85332@vip.qq.com
//aaa er@sina.com.cn
表示用户名部分可以是-、0-9、a-z、A-Z、_、.,可以出现一次或多次,然后是@,域名部分是a-z、A-Z、0-9出现一次或多次,然后是(.再后面是a-z、A-Z出现1次或多次),整个括弧里的可出现1-2次
            while (true)
            {
                Console.WriteLine("请输入一个Email地址:");
                string email = Console.ReadLine();
                Console.WriteLine(Regex.IsMatch(email, @"^[-0-9a-zA-Z_.]+@[a-zA-Z0-9]+(\.[a-zA-Z]+){1,2}$"));
                //-出现在[]第一个不表示范围
                //[-0 - 9a - zA - Z_.]
                //表示在 -、0-9、小写a-z、A-Z、_、.  可以出现一次或多次,然后是@,域名部分是a-z、A-Z、0-9出现一次或多次,然后是(.再后面是a-z、A-Z出现1次或多次),整个括弧里的可出现1-2次


                // \w表示匹配字母或数字或下划线或汉字,即表示能组成单词的字符,即表示[a - zA - Z0 - 9_],汉字是指在Unicode模式下才可以有的。
                // \W除了[a - zA - Z0 - 9_]外的其他字符。
                // \w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* 
                // a.*b  *表示限定前面的表达式或元素出现0次或者多次
            }

判断是否是合法的url地址

csharp 复制代码
    while (true)
 {
       Console.WriteLine("输入一个url:");
       string url = Console.ReadLine();
       bool b = Regex.IsMatch(url, @"^[a-zA-Z0-9]+://.+$");
       Console.WriteLine(b);
}

验证IP地址,4段用.分割的,每段最大为255

csharp 复制代码
            while (true)
            {
                Console.WriteLine("请输入ip:");
                string ip = Console.ReadLine();
                string num = "(25[0-5]|2[0-4]\\d|[1]\\d{2}|[1-9]?\\d)";//说明字符串中\\表示\,所以\\d表示成正则\d,如果不想输入\\,可以在字符串前加@
                bool b = Regex.IsMatch(ip, ("^" + num + "\\." + num + "\\." + num + "\\." + num + "$"));//字符串\\.表示成正则的\.,而\.表示取消.的元字符含义, 如果不想输入\\,可以在字符串前加@
                Console.WriteLine(b);
            }

中文、拆分字符串等常用字符验证技巧

1、含义只要字符串中含有h或email就匹配,比如"1231231email"匹配。

csharp 复制代码
  while (true)
  {
      Console.WriteLine("请输入一个字符串:");
      string msg = Console.ReadLine();
      Console.WriteLine(Regex.IsMatch(msg,"h|email"));
  }

2、含义只要字符串中含有Lmail或email就匹配

csharp 复制代码
while (true)
 {
       Console.WriteLine("请输入一个字符串:");
       string msg = Console.ReadLine();
       Console.WriteLine(Regex.IsMatch(msg,"(h|e)mail"));
}

3、含义:要么是以e开头的,要么是以email结尾的都认为是true

csharp 复制代码
 while (true)
{
    Console.WriteLine("请输入一个字符串");
    string msg = Console.ReadLine();
    Console.WriteLine(Regex.IsMatch(msg,"^e|email$"));
}

4、含义:要么匹配字符串e,要么匹配字符串mail,由于前面加了^,后面加了$,则表示完整匹配,又加了(),则表示完整匹配()里面的,而()里为e或mail

csharp 复制代码
 while (true)
 {
       Console.WriteLine("请输入:");
       string msg = Console.ReadLine();
       Console.WriteLine(Regex.IsMatch(msg,"^(e|mail)$"));
 }

验证输入的是否为中文汉字

csharp 复制代码
 while (true)
{
      Console.WriteLine("请输入中文字符串:");
      string msg = Console.ReadLine();
      Console.WriteLine(Regex.IsMatch(msg,"^[\u4e00-\u9fa5]{1,}$"));
      //\u4e00、\u9fa5分别表示Unicode表中的汉字的头和尾
      //{1, }:匹配上一个元素至少1次
}

使用正则表达式拆分字符串

csharp 复制代码
 while (true)
{
    string msg = "龙傲天下1,枫林天下2,九九归一3,道法自然4";
    string[] strs = Regex.Split(msg, @"\d{0,1}-?\d+");
     foreach (string s in strs)
     {
        Console.WriteLine(s);
     }
     Console.ReadKey();
}

提取字符串中的所有数字

csharp 复制代码
  string msg= "Hello,天天上学,真开心。";
            //字符串提取正则一般不加^ 和 $,加上这两个msg表示要完整匹配正则表达式,否则就表示msg中有部分匹配正则表达式即可
            //Regex.Match只能提取第一个匹配字符串
            //使用\d+而不是\d,\d只能提取单个的数字字符,当然\d用[0-9]代替可行
            Match match = Regex.Match(msg, "[0-9]+ ");
            //+表示上一个元素出现一次或多次,至少得出现一次。
            Console.WriteLine(match.Value);
            //Regex.Matches提取字符串中所有匹配正则的字符串
            MatchCollection matches = Regex.Matches(msg, "[0-9]+");
            foreach (Match item in matches)
            {
                Console.WriteLine(item.Value);
            }
            Console.ReadKey();

提取网页中的邮箱地址等提取分组处理

csharp 复制代码
//xzx@jift.edu.cn 
while (true)
      {
         Console.WriteLine("请输入Email:");
         string email = Console.ReadLine();
         //.除\n(换行)以外的任意的单个字符
         //+表示上一个元素出现一次或多次,至少出现一次
         Match match = Regex.Match(email, @"(.+)@(.+)");
         Console.WriteLine("用户名:{0},域名:{1}",match.Groups[1].Value,match.Groups[2].Value);
     }

字符串替换

csharp 复制代码
public static string Replace(string input,string pattern,string replacement)
input:字符串
pattern:正则表达式(对要替换的部分找规律写正则)
replacement:要替换后的字符串

字符串替换作用------反向引用(叠词处理)

如果匹配的正则字符串中有分组,即有(),可以在该正则中通过\number来反向引用()中的分组字符串。

从左往右,第一对()里的内容用\1引用,第2对()里的内容用\2引用

单词边界与环视的应用

[a-zA-Z0-9_]表示单词字符

\b :表示单词的边界。左边界左边不是单词字符,右边是单词字符;右边界左边是单词字符,右边不是单词字符,\b是指光标所在位置,只判断不匹配,属于"断言"的一种

环视的理解。提取msg字符串中连续3个#的字符串

(?<= )表示环视的逆序,即是判断左边是什么,(?<!= ) 判断左边不是什么

(?= )表示环视的顺序,即是判断右边是什么, (?!= ) 判断右边不是什么

敏感词过滤

在发贴过程中检测用户输入的是否是敏感词,如果是禁止发言,如果有疑问的词提示需要审核,否则提示可以发贴

csharp 复制代码
            //用来存储需要审核的关键词
            StringBuilder sbMode = new StringBuilder();
            //用来存储绝对禁止的关键词
            StringBuilder sbBanned = new StringBuilder();
            string[] lines = File.ReadAllLines("1.txt", Encoding.Default);

            for (int i = 0; i < lines.Length; i++)
            {
                string[] parts = lines[i].Split('=');
                if (parts[1] == "{MOD}")
                {
                    sbMode.AppendFormat("{0}|", parts[0]);
                }
                else if (parts[1] == "{BANNED}")
                {
                    sbBanned.AppendFormat("{0}|", parts[0]);
                }
            }
            sbMode.Remove(sbMode.Length - 1, 1);
            sbBanned.Remove(sbBanned.Length - 1, 1);

常用的实用正则表达式

csharp 复制代码
    只能输入数字:"^[0-9]*$"。
  只能输入n位的数字:"^"d{n}$"。
  只能输入至少n位的数字:"^"d{n,}$"。
  只能输入m~n位的数字:。"^"d{m,n}$"
  只能输入零和非零开头的数字:"^(0|[1-9][0-9]*)$"。
  只能输入有两位小数的正实数:"^[0-9]+(.[0-9]{2})?$"。
  只能输入有1~3位小数的正实数:"^[0-9]+(.[0-9]{1,3})?$"。
  只能输入非零的正整数:"^"+?[1-9][0-9]*$"。
  只能输入非零的负整数:"^"-[1-9][]0-9"*$。
  只能输入长度为3的字符:"^.{3}$"。
  只能输入由26个英文字母组成的字符串:"^[A-Za-z]+$"。
  只能输入由26个大写英文字母组成的字符串:"^[A-Z]+$"。
  只能输入由26个小写英文字母组成的字符串:"^[a-z]+$"。
  只能输入由数字和26个英文字母组成的字符串:"^[A-Za-z0-9]+$"。
  只能输入由数字、26个英文字母或者下划线组成的字符串:"^"w+$"。
  验证用户密码:"^[a-zA-Z]"w{5,17}$"正确格式为:以字母开头,长度在6~18之间,只能包含字符、数字和下划线。
  验证是否含有^%&',;=?$""等字符:"[^%&',;=?$"x22]+"。
  只能输入汉字:"^["u4e00-"u9fa5]{0,}$"
  验证Email地址:"/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/"。
  验证InternetURL:"^http://(["w-]+".)+["w-]+(/["w-./?%&=]*)?$"。
  验证电话号码:"^("("d{3,4}-)|"d{3.4}-)?"d{7,8}$"正确格式为:"XXX-XXXXXXX"、"XXXX- XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"。
  验证身份证号(15位或18位数字):"^"d{15}|"d{18}$"。
  验证一年的12个月:"^(0?[1-9]|1[0-2])$"正确格式为:"01"~"09"和"1"~"12"。
  验证一个月的31天:"^((0?[1-9])|((1|2)[0-9])|30|31)$"正确格式为;"01"~"09"和"1"~"31"。
相关推荐
Azoner5 分钟前
postgresql安装部署(linux)
数据库·postgresql
PyAIGCMaster30 分钟前
文本模式下成功。ubuntu P104成功。
服务器·数据库·ubuntu
drebander42 分钟前
MySQL 查询优化案例分享
数据库·mysql
初晴~1 小时前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
盖世英雄酱581361 小时前
InnoDB 的页分裂和页合并
数据库·后端
YashanDB3 小时前
【YashanDB知识库】XMLAGG方法的兼容
数据库·yashandb·崖山数据库
独行soc3 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍11基于XML的SQL注入(XML-Based SQL Injection)
数据库·安全·web安全·漏洞挖掘·sql注入·hw·xml注入
小林coding3 小时前
阿里云 Java 后端一面,什么难度?
java·后端·mysql·spring·阿里云
风间琉璃""4 小时前
bugkctf 渗透测试1超详细版
数据库·web安全·网络安全·渗透测试·内网·安全工具
drebander4 小时前
SQL 实战-巧用 CASE WHEN 实现条件分组与统计
大数据·数据库·sql