Skip to content
久久日记本
曾经年少爱追梦,一心只想往前飞
  • 首页
  • 博客
    • 博客历史
    • 主题
    • 个人文集
  • 关于
    • 正在读的书
    • 作品归档
    • 2018作品归档
    • 联系我
  • 友情链接
  • 留言板
❄
❅
❆
❄
❅
❆
❄
❅
❆
❄
.NET

C#中的正则表达式

Posted on 2013年5月17日 by 九九 / 2258 Views

本文目录

目录

*1.基础

*2.实例

1.基础

在学习本文之前,可以先阅读和练习下下面链接文档,它是我读过的正则中最好的一篇文章:

.NET进阶系列之一:C#正则表达式整理备忘>>传送门

依靠该篇博文,基本学会了正则表达式!感谢Morven.Huang博主!

WinForm代码片段需要引用的命名空间:

using System.Text.RegularExpressions;

统计匹配弹出框:

MessageBox.Show("r match:"+r.Match(i).Value);
MessageBox.Show(r.IsMatch(i).ToString() + "," + r.Matches(i).Count);

相关练习(参考自上述文章自己的练习):

[email protected] /的用法:

/*@*/
//在相关有"/","""等表达符号特殊字符中要用到;
//  "/"用于转义

2.基本语法字符:

/*基本字符语法*/
//string i = "123?!_";
//Regex r = new Regex(@"\d");//true 数字
//Regex r = new Regex(@"\D");//true 非数字 \d的补集
//Regex r = new Regex(@"\w");//true 单词字符,a-z,A-Z,0-9,_
//Regex r = new Regex(@"\W");//true \w的补集
//Regex r = new Regex(@"\s");//false 空白字符(包括换行符 \n,回车符 \r,制表符 \t,垂直制表符 \v,换页符 \f)
//Regex r = new Regex(@"\S");//true \s的补集
//Regex r = new Regex(".");//true 除换行符\n外的任意字符
//Regex r = new Regex("[...]");//false 匹配[]内所列出的所有字符
//Regex r = new Regex("[5-6]");//flase
//Regex r = new Regex("[^...]");//true 匹配非[]内所列出的字符

3.定位字符:

/*定位字符*/
//string i = "Live for nothing,Die for nothing!";
//Regex r = new Regex("^for nothing");//flase ^ 表示其后的字符串必须位于字符串开始处
//Regex r = new Regex("^Live for");//true 

//Regex r = new Regex("nothing$");//false $ 表示其前面的字符必须位于字符串结束处 
//Regex r = new Regex("nothing!$");//true

/*string i = @"Live for nothing,
Die for nothing!";//多行*/
/*Regex r = new Regex(@"^Live for nothing,
Die for nothing!");//true*/
//Regex r = new Regex("^Live for nothing,\r\nDie for nothing!$");//true
//Regex r = new Regex("^Live for nothing,\r\n$",RegexOptions.Multiline);//false ???
//对于一个多行字符串,在设置了Multiline选项之后,^和$将出现多次匹配

//string i = "Live for nothing,Die for no thing!";
//Regex r = new Regex(@"thing\b");//true,2; b:匹配一个单词的边界;B:匹配一个非单词的边界
//Regex r = new Regex(@"\bthing\b");//true,1;
//Regex r = new Regex(@"\bfor nothing");//true,1;
//Regex r = new Regex(@"\bfor nothing\b");//true,1;

4.重复描述字符:

/*重复描述字符*/
//string i = "1024";//true,1
//string i = "-1023";//true,1
//string i = "-12.12";//false
//Regex r = new Regex(@"^\+?\-?[0-9].?\d{3}$");//匹配+或者- 1(.)000

//string i = "[email protected]";//true ,1
//string i = "[email protected]";
//Regex r = new Regex(@"^\[email protected]\w+.[a-z]+");//验证email地址

5.择一匹配:

/*择一匹配 ( | ) or语句*/
//string i = "0";       //F T 1
//string i = "0.23";  //F T 1
//string i = "100";   //T F 1
//string i = "100.01";//F F 0
//string i = "9.9";   //F T 1
//string i = "99.9";  //F T 1
//string i = "99.";   //F F 0
//string i = "00.1";  //F F 0
//Regex r = new Regex(@"^\+?((100(.0+)*)|([1-9]?[0-9])(\.\d+)*)$");//^\+?((100(\.0)?)|([1-9]?[0-9])(\.\d+)?)$
//匹配0到100的数。最外层的括号内包含两部分“(100(.0+)*)”,“([1-9]?[0-9])(\.\d+)*”,这两部分是“OR”的关系,即正则表达式引擎会先尝试匹配100,如果失败,则尝试匹配后一个表达式(表示[0,100)范围中的数字)。

6.组与非捕获组

/*组与非捕获组*/
//string i = "Live for nothing,Die for something!";
//Regex r = new Regex(@"^Live ([a-z]{3}) no([a-z]{5}),Die \1 some\2!$");//True,1
//正则表达式引擎会记忆“()”中匹配到的内容,作为一个“组”,并且可以通过索引的方式进行引用。表达式中的“\1”,用于反向引用表达式中出现的第一个组,即粗体标识的第一个括号内容,“\2”则依此类推。

//Regex r = new Regex(@"^Live for no([a-z]{5}),Die for some\1!$");//True,1
//MessageBox.Show("Group1 value:"+r.Match(i).Groups[1].Value);//输出thing
//获取组中的内容。注意,此处是Groups[1],因为Groups[0]是整个匹配的字符串,即整个变量x的内容。

//Regex r = new Regex(@"^Live for no(?<g1>[a-z]{5}),Die for some\1!$");
//MessageBox.Show("Group1 value:"+r.Match(i).Groups[1]+",g1 value:"+r.Match(i).Groups["g1"].Value);//thing,thing;true 1
//可根据组名进行索引,使用一下格式为标识一个组的名称(?<groupname>...)

//string i = "Live for nothing nothing";
/*
Regex r = new Regex(@"([a-z]+) \1");
MessageBox.Show("Group1 value:"+r.Match(i).Groups[1].Value);//nothing
i = r.Replace(i,"$1");
MessageBox.Show("var i:"+i);//Live for nothing
//删除原字符串中重复出现的"nothing".在表达式之外,使用"$1"来引用第一个组,下面则是通过组名来引用.
*/

/*
Regex r = new Regex(@"(?<g1>[a-z]+) \1");
MessageBox.Show("Group1 value:"+r.Match(i).Groups["g1"].Value);//thing
i = r.Replace(i,"${g1}");//注意组名要用大括号括起来
MessageBox.Show("var i:"+i);//Live for nothing
*/

/*
Regex r = new Regex(@"^Live for nothing no(?:[a-z]{5})$");
MessageBox.Show("group1 value:"+r.Match(i).Groups[1].Value);//输出为空,
//在组前加上"?:"表示这是个"非捕获组",即引擎将不保存改组的内容
*/

7.贪婪与非贪婪:

/*贪婪与非贪婪*/
//string i = "Live for nothing,Die for nothing";
//Regex r = new Regex(@".*thing");//输出的是 Live for nothing,Die for nothing
//Regex r = new Regex(@".*?thing");//Live for nothing
//正则表达式的引擎是贪婪,只要模式允许,它将匹配尽可能多的字符。通过在“重复描述字符”(*,+)后面添加“?”,可以将匹配模式改成非贪婪。

8.回溯与非回溯:

/*回溯与非回溯*/
//Regex r = new Regex(@".*thing,");//Live for nothing //在r1中,“.*”由于其贪婪特性,将一直匹配到字符串的最后,随后匹配“thing”,但在匹配“,”时失败,此时引擎将回溯,并在“thing,”处匹配成功。
//Regex r = new Regex(@"(?>.*)thing,");//在r2中,由于强制非回溯,所以整个表达式匹配失败
//MessageBox.Show("match value:"+r.Match(i).Value);
//使用“(?>…)”方式进行非回溯声明。由于正则表达式引擎的贪婪特性,导致它在某些情况下,将进行回溯以获得匹配,

9.正向预搜索,反向预搜索:

/*正向预搜索,反向预搜索*/
string i = "1024 used 2048 free";
//Regex r = new Regex(@"\d{4}(?= used)");//1024
//Regex r = new Regex(@"\d{4}(?! used)");//2048
//r1中的正声明表示必须保证在四位数字的后面必须紧跟着“ used”,r2中的负声明表示四位数字之后不能跟有“ used”。
//正向预搜索声明格式:正声明 “(?=…)”,负声明 “(?!...)” ,声明本身不作为最终匹配结果的一部分,
/*反向预搜索   类似*/
2.案例

学习了C#中的正则表达式,自己尝试了写了一些提取相关信息和匹配验证,马马虎虎.

引用命名空间:

using System.Text.RegularExpressions;

案例1:验证email地址:
注册时常会用到email绑定,验证email的合法性在此.

WinForm界面:

TextBox: txtemail;
Button: btnCheck;

btnCheck点击事件:

private void btnCheck_Click(object sender, EventArgs e)
{
    string i = txtemail.Text.Trim();
    Regex r = new Regex(@"^\[email protected]\w+.[a-z]+");//[email protected]
    if (r.IsMatch(i))
    {
        MessageBox.Show("格式正确!");
    }
    else
    {
        MessageBox.Show("格式错误!");
    }
}

案例2:提取网页源码的ed2k链接:

(1)对VeryCD的备份中会用到提取链接,可以先遍历网页的id号;

(2)根据url获取网页源码并利用正则表达式 提取ed2k链接 和对应的标题;

(3)存入listbox并写入为txt文本.

关于这些 备份VeryCD 和RSS阅读器 的相关实现会在后面研究.

WinForm界面:

TextBox: txtemail;

Button: btnCheck;

btnCheck点击事件:

private void btngeted2k_Click(object sender, EventArgs e)
{
    string i = txtemail.Text.Trim();
    Regex r = new Regex(@"[ed2k://|]{8}[a-z]+[|][^|]?\w+[.]+[^|]+[|]");//匹配ed2k链接
    //string j = r.Match(i).ToString();
    MatchCollection j = r.Matches(i);
    //j = j.Substring(0, j.Length - 1);
    //去掉提取字符串的换行,因为假如保存的源码中txt文本自动换行的话
    if (r.IsMatch(i))
    {
        string str="",temp="";
        for (int c = 0; c < j.Count; c++)
        {
            temp=j[c].ToString();
            str += temp.Substring(0, temp.Length - 1)+"\n\n";
        }

        MessageBox.Show(str);
        //MessageBox.Show(r.Match(i).ToString());

    }
    else
    {
        MessageBox.Show("尚未提取出ed2k链接!");
    }
}

案例3:提取cnblogs首页的文章链接地址:

适合做个RSS阅读,只保留文字.

主界面同上

private void btnGetCnblogs_Click(object sender, EventArgs e)
{
    string i = txtemail.Text.Trim();
    Regex r = new Regex(@"[a-z]{4}[:]+//[w]{3}[^ ]+/[0-9]+.[html]{4}");
    MatchCollection j = r.Matches(i);
    if (r.IsMatch(i))
    {
        string str="";
        for (int c = 0; c < j.Count; c++)
        {
            if (c + 1 < j.Count)
            {
                if (j[c].ToString() != j[c + 1].ToString())
                    //去掉相邻两个重复的链接,当相邻两个链接不相等时才将前一个存入str;
                    //因为博客园里面同一篇文章会提取出相同的三个链接
                {
                    //list.Add(j[c].ToString());
                    str += j[c].ToString() + "\n\n";
                }
            }
        }
        str=str+j[j.Count - 1].ToString();

        MessageBox.Show(str);
        //MessageBox.Show(r.Match(i).ToString());

    }
    else
    {
        MessageBox.Show("尚未提取cnblogs文章链接!");
    }
}
C#
九九
过去的我们,现在的自己,往事,终会随风而逝。 View all posts by 九九 →

Post navigation

Older post
简单工厂模式
Newer post
5段小代码理解JS核心,闭包和作用域

标签云

2019ncov Android ASP.NET Baby C# C/C++ CSS Div DX11 flask front-end GAE Git Java JJProject JS Life MSSQL MVC OpenSource Oracle Python React React-Native Software Tools Vue Webpack Website Window WP7 乱记 十年旧梦 天气 宝宝成长日记 小说 工作 情感 故障 散文 日记 网新实训笔记 花落梧桐 诗间集 转载

时光机

  • 2023年3月
  • 2023年2月
  • 2022年12月
  • 2022年4月
  • 2022年3月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年5月
  • 2019年12月
  • 2019年10月
  • 2019年9月
  • 2019年6月
  • 2019年5月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年3月
  • 2018年2月
  • 2018年1月
  • 2017年11月
  • 2017年10月
  • 2017年9月
  • 2017年7月
  • 2017年3月
  • 2017年1月
  • 2016年12月
  • 2016年11月
  • 2016年10月
  • 2016年7月
  • 2016年3月
  • 2016年2月
  • 2016年1月
  • 2015年12月
  • 2015年11月
  • 2015年10月
  • 2015年9月
  • 2015年8月
  • 2015年7月
  • 2015年4月
  • 2015年3月
  • 2015年2月
  • 2015年1月
  • 2014年12月
  • 2014年11月
  • 2014年10月
  • 2014年9月
  • 2014年8月
  • 2014年7月
  • 2014年6月
  • 2014年5月
  • 2014年4月
  • 2014年3月
  • 2014年2月
  • 2014年1月
  • 2013年12月
  • 2013年11月
  • 2013年10月
  • 2013年9月
  • 2013年8月
  • 2013年7月
  • 2013年6月
  • 2013年5月
  • 2013年4月
  • 2013年3月
  • 2013年1月
  • 2012年11月
  • 2012年10月
  • 2012年9月
  • 2012年8月
  • 2012年7月
  • 2012年6月
  • 2012年5月
  • 2012年4月
  • 2012年3月
  • 2012年2月
  • 2012年1月
  • 2011年12月
  • 2011年11月
  • 2011年10月
  • 2011年9月
  • 2011年8月
  • 2011年6月
  • 2011年5月
  • 2011年4月
  • 2011年3月
  • 2011年2月
  • 2010年12月
  • 2010年11月
  • 2010年10月
  • 2010年9月
  • 2010年8月
  • 2010年6月
  • 2010年5月
  • 2010年2月
  • 2010年1月
  • 2009年12月
  • 2009年11月
  • 2009年10月
  • 2009年9月
  • 2009年8月
  • 2009年7月
  • 2009年6月
  • 2009年5月
  • 2009年4月
  • 2009年3月
  • 2009年2月
  • 2009年1月
  • 2008年8月
  • 2008年6月
  • 2008年5月
  • 2008年4月
  • 2008年2月
  • 2007年11月
  • 2007年8月
  • 2007年6月
  • 2007年5月
  • 2007年4月
  • 2007年3月
  • 2007年2月
  • 2007年1月
  • 2006年10月
  • 2006年8月
© 2006 - 2023 久久日记本
Powered by WordPress | Theme: Graphy for 99diary