代码示例
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Windows.Forms; 10 using System.Text.RegularExpressions; 11 12 namespace RegularExpression 13 { 14 public partial class Form1 : Form 15 { 16 public Form1() 17 { 18 InitializeComponent(); 19 } 20 21 private void Form1_Load(object sender, EventArgs e) 22 { 23 24 } 25 26 private void BtnRegexTest_Click(object sender, EventArgs e) 27 { 28 string sInput = TextValue.Text.Trim(); 29 //CheckPostcode(sInput); //判断邮编 30 //CheckPhone(sInput); //判断电话号码 31 //CheckIdCard(sInput); //验证中国身份证号 32 CheckEmail(sInput); //验证邮箱 33 34 } 35 36 #region 验证邮箱 37 /// <summary> 38 /// 验证邮箱 39 /// </summary> 40 /// <param name="sVal">传递的邮箱</param> 41 private void CheckPostcode(string sVal) 42 { 43 //第一邮政编码的验证 44 //邮政编码是六位的纯数字 45 //用IsMacth这个函数 46 47 bool bReturn = Regex.IsMatch(sVal, "^[0-9]{6}$"); 48 if (bReturn) 49 MessageBox.Show("是邮编"); 50 else 51 MessageBox.Show("不是邮编"); 52 //[]字符组,表示在字符组中罗列出来的字符串,任意取单个 53 //{}表示匹配指定的数量,有如下几种形式: 54 //{n}表示匹配n个 55 //{n,}匹配从n开始,上不封顶 56 //{n,m}匹配从n开始到m个 57 //[0-9]{6},这样写表示只要你输入的字符串中有满足六位数字就返回True,所以aaa123456、123456aaa判定为True 58 // ^ 表示从某个字符串开始 59 // $ 表示以某个字符串结尾 60 } 61 #endregion 62 63 #region 手机号判定 64 /// <summary> 65 /// 验证手机号 66 /// </summary> 67 /// <param name="sVal">传递输入的号码</param> 68 private void CheckPhone(string sVal) 69 { 70 //bool bReturn = Regex.IsMatch(sVal, "^[0-9]{11}$"); 71 //继续升级代码,加强判断 72 //bool bReturn = Regex.IsMatch(sVal, "^1[3-9][0-9]{9}$"); 73 74 //[0-9]等价于 \d,@表示里面的都是字符,不需要转义 75 // \D与\d相反,表示所有的非数字 76 bool bReturn = Regex.IsMatch(sVal, @"^1[3-9]\d{9}$"); 77 78 if (bReturn) 79 MessageBox.Show("是手机号", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information); 80 else 81 MessageBox.Show("不是手机号", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 82 83 } 84 #endregion 85 86 #region 验证中国居民身份证号 87 /// <summary> 88 /// 验证中国居民身份证号 89 /// </summary> 90 /// <param name="sVal">传递输入的身份证号</param> 91 private void CheckIdCard(string sVal) 92 { 93 //身份证原理(前提是中国居民的身份证号) 94 //要么是15位,要么是18位,如果是18位末尾要么是数字,要么是小写或大写的X 95 //bool bReturn = Regex.IsMatch(sVal, "^([1-9][0-9]{14}|[1-9][0-9]{16}[0-9Xx])$"); 96 //bool bReturn = Regex.IsMatch(sVal, "^[1-9][0-9]{14}$|^[1-9][0-9]{16}[0-9Xx]$"); 97 98 //用 ? 稍加改进 99 bool bReturn = Regex.IsMatch(sVal, "^[1-9][0-9]{14}([0-9]{2}[0-9Xx])?$"); 100 101 if (bReturn) 102 MessageBox.Show("是身份证号", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information); 103 else 104 MessageBox.Show("不是身份证号", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 105 106 //正则表达式 | 竖杠表示或,运算级别最低 107 //知识点 ?问号,限定符,限定前面的表达式出现0次或者1次;终止贪婪模式 108 109 } 110 #endregion 111 112 #region 验证邮箱 113 /// <summary> 114 /// 验证邮箱 115 /// </summary> 116 /// <param name="sVal">传第递输入的邮箱</param> 117 private void CheckEmail(string sVal) 118 { 119 //邮箱至少有一个@符号。@右边一般为一个一级域名或者二级域名 120 //bool bReturn = Regex.IsMatch(sVal, @"^[-a-zA-Z0-9_.]+@[-a-zA-Z0-9]+(\.[A-za-z]+){1,2}$"); 121 122 bool bReturn = Regex.IsMatch(sVal, @"^\w+([-.]\w+)*@\w+([-\.]\w+)*\.\w+([-.]\w)*$"); 123 124 if (bReturn) 125 MessageBox.Show("是邮箱", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information); 126 else 127 MessageBox.Show("不是邮箱", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 128 // . 点,表示:除了\ n 和 \r之外的任何单个字符 129 // \w :匹配包括下划线的任何单个字符,接近于[A-Za-z0-9_](排除unicode字符外,就是等价) 130 } 131 #endregion 132 } 133 }
1、元字符
特定含义的字符
代码 | 说明 |
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线或汉字 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\b | 匹配单词的开始或结束 |
^ | 匹配字符串的开始(在集合字符里[^a]表示非(不匹配)的意思) |
$ | 匹配字符串的结束 |
2、反义字符
多用于查找除某个字符以外其他字符均可以的情况
代码 | 说明 |
\W | 匹配任意不是字母、数字、下划线、汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[^X] | 匹配除了X以外的任意字符 |
[^sfdcx] | 匹配除了sfdcx这几个字母以外的任意字符 |
3、限定字符
多用于重复匹配次数
代码 | 说明 |
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
4、转义字符
前面加 \
5、字符分支
用 | 将不同条件分割开来
6、字符分组
多用于将多个字符重复,主要通过 ( ) 进行分组
例如:(\d\w){3} 重复匹配3次 (\d\w)
常用分组语法
分类 | 代码 | 说明 |
捕获 | (exp) | 匹配exp,并捕获文本到自动命名的组里 |
(?<name>exp) | 匹配exp,并捕获文本到名称为name的组里,也可以写成 (?'name'exp) | |
(?:exp) | 匹配exp,不捕获匹配的文本,也不给此分组分配组号 | |
零宽断言 | (?=exp) | 匹配exp前面的位置 |
(?<=exp) | 匹配exp后面的位置 | |
(?!exp) | 匹配后面跟的不是exp的位置 | |
(?<!exp) | 匹配前面不是exp的位置 | |
注释 | (?#comment) | 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读 |
7、懒惰匹配和贪婪匹配
贪婪匹配:正则表达式中包含重复的限定符时,通常的行为是匹配 尽可能多 的字符。
懒惰匹配:有时候需要匹配尽可能少的字符。
常用的懒惰匹配限定符如下
代码 | 说明 |
*? | 重复任意次,尽可能少重复 |
+? | 重复一次或更多次,但尽可能少重复 |
?? | 重复0次或一次,但尽可能少重复 |
{n,m}? | 重复n到m次,但尽可能少重复 |
{n,}? | 重复n次以上,但尽可能少重复 |
8、后向引用
使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推
示例:\b(\w+)\b\s+\1\b可以用来匹配重复的单词,像go go, 或者kitty kitty。
这个表达式首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字(\b(\w+)\b),这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符(\s+),最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)。
你也可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?<Word>\w+)(或者把尖括号换成'也行:(?'Word'\w+)),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k<Word>,所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b
9、零宽断言
有时候需要查找某些匹配之前或之后的东西,这个时候就需要用到们像\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言
(?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。
(?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。
参考文章:点这里