断言

  判断某个位置左侧或者右侧是否符合匹配。常见断言有三种,单词边界、行起始/结束位置、环视。阅读本章前,建议先下载我于CSDN上传的示例代码,下载无需分数,下载链接

1.单词边界

  正则表达式"\b"用于匹配单词的边界。实际上他匹配一个这样的位置,这个位置一边匹配"\w",一边不匹配"\w"。例如,输入字符串"I Love China!",若用正则表达式"\b\w+\b"来匹配,则能捕获子字符串"I","Love","China"。

2.行起始/结束位置

  行起始位置可用"^"匹配,行结束位置可用"$"匹配。这个看起来十分简单,但是有一点需要十分注意。当他们在单行模式下和在多行模式下能匹配的位置是不同的。起初在我学习正则表达式时,误以为单行模式是将输入的字符串看成是单行的,多行模式则看成多行。其实后来通过代码的测试并且看了一些其他的博客,才理解其实单行模式和多行模式,只是影响某一些正则表达式字符所能匹配的字符串而已。下面做出我对单行模式和多行模式的理解。

  首先,通过看资料得知在Windows平台下,每一行的换行符总是"\r\n"这样的。而其他平台的换行符则是"\n"这样的。

  单行模式下,"^"比较简单,即匹配文本的最开始的位置,不管你这个输入文本是单行的还是多行的。多行模式下,"^"除了具有单行模式的能力外,还能匹配"\n"之后的位置。但是不能匹配"\r"后面的位置,当时看了某篇博文误导了好久。Regex类下的Replace方法,对匹配的字符串替换成你想要的字符串。若匹配的是位置,这实际上是在该位置上添加你想要的字符串。  

Regex regex = new Regex("^");//默认所有都为单行模式
string replace = regex.Replace("abc\n", "|");//"|abc\n" 该值通过断点得出而非控制台
regex = new Regex("^", RegexOptions.Multiline);//多行模式
replace = regex.Replace("abc\n", "|");//"|abc\n|" 该值通过断点得出而非控制台

  单行模式下,"$"匹配文本的最后位置,其实这里说最后位置是不准确的,我无法给出一个准确的词语描述,只能同过代码来让你们注意某些事情。多行模式下,同样除了具有单行模式的能力外还能匹配"\n"之前的位置,并且也是不能匹配"\r"前面的位置。

Regex regex = new Regex("$");//默认所有都为单行模式
string replace = regex.Replace("abc\nabc\n", "|");//"abc\nabc|\n|" 该值通过断点得出而非控制台
replace = regex.Replace("abc\nabc\nabc", "|");//"abc\nabc\nabc|" 该值通过断点得出而非控制台
regex = new Regex("$", RegexOptions.Multiline);//多行模式
replace = regex.Replace("abc\nabc\n", "|");//"abc|\nabc|\n|" 该值通过断点得出而非控制台

  看到以上结果了吗,单行模式下的"$",如果是以"\n","\r\n"结尾的,除了匹配他们之后的位置,也会匹配他们之前的位置,导致得出第一个replace的结果。如果不以"\n","\r\n"结尾的则没有争议的在最后位置上匹配了。多行模式下同样有这个问题。为了解决这个问题,可以用"\z"来保证匹配字符串的最后一个位置,但是也不再有多行模式下的能力了。

Regex regex = new Regex(@"\z");//默认所有都为单行模式
string replace = regex.Replace("abc\nabc\n", "|");//"abc\nabc\n|" 该值通过断点得出而非控制台
replace = regex.Replace("abc\nabc\nabc", "|");//"abc\nabc\nabc|" 该值通过断点得出而非控制台
regex = new Regex(@"\z", RegexOptions.Multiline);//多行模式
replace = regex.Replace("abc\nabc\n", "|");//"abc\nabc\n|" 该值通过断点得出而非控制台

3.环视

  环视的作用是,当匹配到某个位置的时候,我们要确定该位置的左边或右边是否匹配我们设定的正则表达式,若是,则该位置匹配,继续完成后面的匹配,若否,则不匹配,也无需继续后面的匹配了。环视语法:往右环视,即顺序环视"(?=regStr)","(?!regStr)",其中"="表示肯定,"!"表示否定,即要不要匹配的问题。往左环视,即逆序环视"(?<=regStr)","(?<!regStr)"。

  例子1:外国人的数字通常喜欢用","去分隔,如有一个数字在中国是这样的"123456789",在过外就变成这样了"123,456,789"。我们可以总结出这样的规律,在这样一个位置上添加",",该位置的右边必须是3倍个数的数字,该位置的左边还必须有数字。这样,我们写出了正则表达式"(?<=\d)(?=(?:\d{3})+)"

Regex regex = new Regex(@"(?<=\d)(?=(?:\d{3})+)");
Console.WriteLine(regex.Replace("", ","));//1,2,3,4,5,6,789

  嗯,看来我们的思维还不够缜密,并不能一次编写正确的正则表达式,不过没关系,出现bug后我们可以立刻修正bug。导致这个bug的原因在于顺序环视时,当我们环视匹配完3倍个数的数字后,还必须保证他的后面再也没有数字了。找到问题的关键,我们来写出新的正则表达式"(?<=\d)(?=(?:\d{3})+(?!\d))"。在环视内部可以再嵌套一个环视。

Regex regex = new Regex(@"(?<=\d)(?=(?:\d{3})+(?!\d))");
Console.WriteLine(regex.Replace("", ","));//123,456,789
Console.WriteLine(regex.Replace("", ","));//1,234,567,890

  例子2:当我们得到一个这样无序的,包含数字和字母的字符串"1sf2sdf333sf55ew2156we98552af3sd5fas6654sdfa65assfd56"时,我们可以相当容易的用"\d+"来捕获其中的数字,但如果我不要求捕获这些数字,而是要求将数字用括号括起来,并将字符串返回怎么办。思路,我们要匹配的是一个位置,并在这个位置上加上括号。这个位置可以很简单的想到,他的一边是数字,一边不是数字。当然,我们要分两步实现这个功能,第一步,先用正则表达式"(?<!\d)(?=\d)"匹配数字开始的位置。第二部,用正则表达式"(?<=\d)(?!\d)"匹配数字结束的位置。是不是十分方便,用这么少的代码便完成了我们以前不敢想的功能。

Regex regex = new Regex(@"(?<!\d)(?=\d)");//匹配数字开头
string replace = "1sf2sdf333sf55ew2156we98552af3sd5fas6654sdfa65assfd56";
replace = regex.Replace(replace,"(");//"(1sf(2sdf(333sf(55ew(2156we(98552af(3sd(5fas(6654sdfa(65assfd(56"
regex = new Regex(@"(?<=\d)(?!\d)");//匹配数字结尾
replace = regex.Replace(replace, ")");//"(1)sf(2)sdf(333)sf(55)ew(2156)we(98552)af(3)sd(5)fas(6654)sdfa(65)assfd(56)"
Console.WriteLine(replace);

  断言暂时介绍这么多,谢谢!

.NET正则表达式基础入门(四)的更多相关文章

  1. .NET正则表达式基础入门

    这是我第一次写的博客,个人觉得十分不容易.以前看别人写的博客文字十分流畅,到自己来写却发现十分困难,还是感谢那些为技术而奉献自己力量的人吧. 本教程编写之前,博主阅读了<正则指引>这本入门 ...

  2. Swift语法基础入门四(构造函数, 懒加载)

    Swift语法基础入门四(构造函数, 懒加载) 存储属性 具备存储功能, 和OC中普通属性一样 // Swfit要求我们在创建对象时必须给所有的属性初始化 // 如果没办法保证在构造方法中初始化属性, ...

  3. C#基础入门 四

    C#基础入门 四 方法参数 值参数:不附加任何修饰符: 输出参数:以out修饰符声明,可以返回一个或多个给调用者: 如果想要一个方法返回多个值,可以用输出参数来处理,输出参数由out关键字标识,如st ...

  4. .NET正则表达式基础入门(一)

    字符组 正则表达式的字符组十分简单,就是列出你所想要匹配的字符.阅读本章前,建议先下载我于CSDN上传的示例代码,下载无需分数,下载链接. 1.普通字符组 普通字符组,列出所有你需要匹配的字符. 例如 ...

  5. .NET正则表达式基础入门(二)

    量词 正则表达式的量词用于表明前面的子表达式需要匹配的次数.阅读本章前,建议先下载我于CSDN上传的示例代码,下载无需分数,下载链接. 1.量词的一般形式 "{n}"," ...

  6. .NET正则表达式基础入门(三)

    括号 正则表达式中的括号能将多个字符或者表达式当做一组,即将他们看成一个整体.这样量词就可以修饰这一组表达式.阅读本章前,建议先下载我于CSDN上传的示例代码,下载无需分数,下载链接. 1.分组 假设 ...

  7. PHP正则表达式基础入门

    思维导图 介绍 正则表达式,大家在开发中应该是经常用到,现在很多开发语言都有正则表达式的应用,比如JavaScript.Java..Net.PHP 等,我今天就把我对正则表达式的理解跟大家唠唠,不当之 ...

  8. D3基础入门四-事件处理

    6.5.0版 .on("mouseover", function(e,d) e: {"isTrusted":true} 第二个参考才是数据,但这在不同的环境可能 ...

  9. Mybatis框架基础入门(四)--SqlMapConfig.xml配置文件简介

    SqlMapConfig.xml中配置的内容和顺序如下: properties(属性) settings(全局配置参数) typeAliases(类型别名) typeHandlers(类型处理器) o ...

随机推荐

  1. C#多线程之基础篇3

    在上一篇C#多线程之基础篇2中,我们主要讲述了确定线程的状态.线程优先级.前台线程和后台线程以及向线程传递参数的知识,在这一篇中我们将讲述如何使用C#的lock关键字锁定线程.使用Monitor锁定线 ...

  2. 【Machine Learning】Python开发工具:Anaconda+Sublime

    Python开发工具:Anaconda+Sublime 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现 ...

  3. 关于font-family

    在设置页面字体的时候,你会发现在 font-family 属性中会设置好多个字体,想看懂它们都是什么字体吗?不好意思,我不是搞设计的,我也不知道.那么,现在写的东西,只是对于一个前端人员来说,要了解的 ...

  4. 基于NPOI的Excel数据导入

    从Excel导入数据最令人头疼的是数据格式的兼容性,特别是日期类型的兼容性.为了能够无脑导入日期,折腾了一天的NPOI.在经过测试确实可以导入任意格式的合法日期后,写下这篇小文,与大家共享.完整代码请 ...

  5. 星浩资本快速发展引擎:IT就是生产力

    星浩资本成立于2010年,是一家涵盖私募基金.开发管理.商业与现代服务业三大业务范围的综合性管理公司,专注于投资中国首创.高成长性.高回报率的创新型城市综合体. 年轻的星浩资本在商业投资上有其独到的商 ...

  6. ASP.NET Core "完整发布,自带运行时" 到jexus

    一.阅读前须知   1.使用 jexus整合asp.net core的优点:       1)支持多站点,同一端口可以同时支持任何多的asp.net core应用程序:      2)应用程序启动.停 ...

  7. About me

    stay hungry, stay foolish VaJoy / 蓝邦珏 Addr:Tencent Shenzhen E-Mail:vajoy@qq.com 站内:http://space.cnbl ...

  8. K-近邻算法(KNN)

    简介 k近邻算法是数据分类一种常用的算法,属于监督学习算法的一类,它采用不同特征值之的距离进行分类.K近邻算法具有精度高.对异常值不敏感.无数据输入假定的优点,缺点是计算复杂度高.空间复杂度高.适用于 ...

  9. 微信小程序开发调试工具

    为了帮助开发者简单和高效地开发微信小程序,我们推出了全新的 开发者工具 ,集成了开发调试.代码编辑及程序发布等功能. 扫码登录 启动工具时,开发者需要使用已在后台绑定成功的微信号扫描二维码登录,后续所 ...

  10. 二、Redis基本操作——String(实战篇)

    小喵万万没想到,上一篇博客,居然已经被阅读600次了!!!让小喵感觉压力颇大.万一有写错的地方,岂不是会误导很多筒子们.所以,恳请大家,如果看到小喵的博客有什么不对的地方,请尽快指正!谢谢! 小喵的唠 ...