.NETCoreCSharp 中级篇2-4

本节内容为正则表达式的使用

简介

有的时候,你是否有过这种需求:判断一个Ip地址、邮箱、密码规则是否合法。如果让你使用if一类的传统方法进行处理,你肯定会被逼疯的。而对于绝大多数的编程语言而言,都有一个字符串处理利器————正则表达式。它可以轻松的让字符串和规则匹配上。有点这样的意思,从前你是判断字符串,去遍历它,而有了正则表达式,你是在书写一个通用性质的规则,让字符串与规则进行匹配。正则表达式本质上就是一串蕴含了一些特殊字符规则的字符串,因此我们书写正则表达式其实是在书写一个字符串,只是它代表了一定的规则而已。

常见的几种正则符号

事实上正则表达式没有过多的知识点,只是一些技巧性的训练,但请相信我,正则表达式是非常重要的。熟练的使用下列的正则符号会对你大有脾益。

元字符

元字符 说明
. 匹配除了换行符以外的任意字符
\w 匹配字母、数字、下划线以及汉字
\s 匹配任意空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束

1.例如匹配abc开头的字符串

\babc 或者 ^abc

2.匹配5位数字的字符串

^\d\d\d\d\d$

重复限定符号

有了元字符就可以写不少的正则表达式了,但细心的你们可能会发现:别人写的正则简洁明了,如果你只使用元字符进行正则表达式的书写,既不美观也不实用,因此我们使用重复限定符进行重复数据的处理,下面我们来看一些限定符:

字符 说明
* 重复0次或多次
+ 重复一次或一次以上
? 重复0次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

现在我们就能书写相当美观的正则表达式了,例如:

1.匹配7位数字的电话号码

^\d{7}$

2.匹配138开头的手机号

^138\d{8}

3.匹配a开头,若干个b结尾的字符串

^ab*$

分组

现在我们已经学会以一点关于书写正则表达式的方法,不过,我们现在无论是匹配还是重复都是针对单个字符进行操作,假如说我希望匹配一个以ab为循环的重复字符串应该如何去处理呢?

答案很简单,就是分组,分组我们通常使用()进行分组,例如匹配以ab为循环的字符串为:

^(ab)*

转义字符

有的时候,我们需要匹配的字符串中本身就含有正则表达式中的关键字符,我们则需要转义,例如我们需要匹配(ab)为循环的字符串:

^(\(ab\))*

反斜杠\就是我们的转义字符。不过对于C#中,字符串含有反斜杠会自动转义,为了避免这种情况,我们需要在字符串之前加上@或者将将转义字符转义,也就是\两个斜杠

条件或

有的时候,我们需要匹配的字符串可能是ab开头也有可能是cd开头,这个时候我们就使用条件语句处理,例如:

^(ab|cd)*

用逻辑或“|”进行处理。

区间匹配

有的时候,我们有可能是需要匹配比如说138-150之间所有数字开头的字符串,或者说A-F按字母表顺序内的字母开头,我们可以这样

^[138-150]*
^[A-F]*

反义

之前我们谈论的都是字符串中含有什么什么,现在我们可能需要匹配到字符串中不含有的字符,那么我们就需要使用反义,如下表

元字符 说明
\W 匹配不是字母、数字、下划线以及汉字
\S 匹配不是空白符
\D 匹配不是数字
\B 匹配不是单词的开始或结束
[^x] 匹配出了x以外的任意字符

贪婪模式与懒惰模式

贪婪

贪婪是当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符,这匹配方式叫做贪婪匹配。特性:一次性读入整个字符串进行匹配,每当不匹配就舍弃最右边一个字符,继续匹配,依次匹配和舍弃(这种匹配-舍弃的方式也叫做回溯),直到匹配成功或者把整个字符串舍弃完为止,因此它是一种最大化的数据返回,能多不会少。

事实上我们之前所谈论的重复限定符就是一种贪婪量词

举个例子例如我们需要匹配由2-5个数字组成的字符串,假设有这样一串数字51354 8454 1 568,使用^\d{2,5}进行匹配的结果是51354 8454 568,事实上对于这些而言,匹配两个就已经满足了,例如51已经满足该正则式,但是在贪婪匹配中,它会尽可能的多匹配,将整个字符串输出。

如果多个贪婪量词叠加在一起,如果字符串能满足他们各自最大程度的匹配时,就互不干扰,但如果不能满足时,会根据深度优先原则,也就是从左到右的每一个贪婪量词,优先最大数量的满足,剩余再分配下一个量词匹配。

懒惰

懒惰匹配:当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能少的字符,这匹配方式叫做懒惰匹配。特性:从左到右,从字符串的最左边开始匹配,每次试图不读入字符匹配,匹配成功,则完成匹配,否则读入一个字符再匹配,依此循环(读入字符、匹配)直到匹配成功或者把字符串的字符匹配完为止。

使用懒惰量词就是在贪婪量词后面中加?,对于之前的例子,他会匹配成51 35 84 54 56

拓展

零宽断言

零宽断言用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。最好还是拿例子来说明吧: 断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配。

非常抽象而且笼统,对吧,事实上我也那么觉得,以上内容来自百度百科,因为我实在是很难解释这个东西,你可以理解为匹配不含正则结果的内容吧。

正向先行断言(正前瞻)

正前瞻的语法为:

//pattern为正则式
(?=pattern)

它用于匹配pattern表达式之前的内容,并不返回本身。感觉还是很奇怪对吧,举一个例子:今年我市GDP为5600亿元。假设你要将这句话中的5600取出来,你使用正前瞻的方式应该怎么做?

\d+(?=亿元)

正向后行断言(正后顾):

正后顾的语法为:

//pattern为正则式
(?<=pattern)

与正前瞻相反,他是返回pattern之后的内容,如果继续实现之前的内容,那么表达式就会变成

(<=今年我市GDP为)\d+

负向先行断言(负前瞻)

负前瞻的语法为:

//pattern为正则式
(?!pattern)

匹配非pattern表达式的前面内容,不返回本身。还是举之前的例子,我要找到5600亿元之前的字母,那么可以是

[A-Z]+(?!5600亿元)

负向后行断言(负后顾)

这个想必我不需要进行讲解各位也应当能思考出如何书写及使用了,他的语法类似的是:

//pattern为正则式
(?<!pattern)

作用当然是匹配非pattern之后的内容。

我在这里就举这几个例子,还有一些很好的使用手册你可以参考Microsoft Documents

捕获与非捕获

捕获你可以理解为将表达式按组分配,例如你匹配一个电话010-8511561,010是区号,我们有可能利用正则式将它单独取出来。

数字编号捕获组

语法就是我们之前的分组,但是匹配这个电话号码的时候,他的表达式如果是

((\d{3})-(\d{7}))

那么他会分为三组,第一组是完整的电话,第二组是我们的区号,第三组是我们的电话号码。

命名编号捕获组

语法:

(?<name>exp)

这个name就是你自己自定义的,例如之前的我们可以写成

(?<quhao>\d{3})-(?<haoma>\d{7})

这样我们可以通过名称进行访问组内数据,具体的使用我会在后面进行讲解。

非捕获组

同之前相反,它用于表示不需要分组的数据

(?:exp)

例如我们不需要区号,那么正则式就变成了

(?:\d{3})-(\d{7})

反向引用

捕获会返回一个捕获组,这个分组是保存在内存中,不仅可以在正则表达式外部通过程序进行引用,也可以在正则表达式内部进行引用,这种引用方式就是反向引用。

同样的,根据捕获组命名规则,反向引用也有两种

1- 数字反向引用:\k或\number

2- 命名反向引用:\k或'name'

反向引用通常和捕获组是一同使用的,它的作用主要是用来查找一些重复的内容或者做替换指定字符。比如要查找一串字母"aabbbbgbddesddfiid"里成对的字母。

我们捋捋思路:

  • 首先我们要有一个匹配字母的捕获组:(\w)
  • 然后(\w)\1

这样就可以了,\1代表的是1分组,这样就是一个匹配成对字母的正则式了。

如何使用正则表达式

位于 System.Text.RegularExpressions 空间下的 Regex 可以对正则表达式进行处理。

Match

这是匹配结果的对象,内含这几个常用的属性及方法

  • Value:匹配值
  • Groups:分组
  • Index:匹配值的第一个字符的索引
  • Success:是否符合正则式
  • NextMatch:下一个符合的匹配值

Regex.Matches

匹配多个符合的结果,返回一个MatchCollection数组,使用foreach并转换成Match对象进行访问.

  • IsMatch:是否符合正则式
  • Replace:替换匹配上正则式的字符串
  • Split:按匹配上的字符串进行分割
  • Match:返回第一个符合正则式的字符串
  • Matches:返回所有符合的字符串

Reference

老刘

如果我的文章帮助了您,请您在github.NETCoreGuide项目帮我点一个star,在博客园中点一个关注和推荐。

Github

BiliBili主页

WarrenRyan'sBlog

博客园

.NETCore C# 中级篇2-4 一文带你完全弄懂正则表达式的更多相关文章

  1. .NETCore C# 中级篇2-6 Json与XML

    .NETCoreCSharp 中级篇2-6 本节内容为Json和XML操作 简介 Json和XML文本是计算机网络通信中常见的文本格式,其中Json其实就是JavaScript中的数组与对象,体现了一 ...

  2. 【matlab 基础篇 03】一文带你全面了解 plot 绘图函数的使用(超详细+图文并茂)

    快速入门matlab,系统地整理一遍,如何你和我一样是一个新手,那么此文很适合你: 文章目录 1 前言 2 plot 2.1 显示正弦波 2.2 修改颜色 2.3 修改点的形状 2.4 修改线的形状 ...

  3. 一文让你完全弄懂Stegosaurus

    国内关于 Stegosaurus 的介绍少之又少,一般只是单纯的工具使用的讲解之类的,并且本人在学习过程中也是遇到了很多的问题,基于此种情况下写下此文,也是为我逝去的青春时光留个念想吧~ Stegos ...

  4. 面试都在问的微服务、服务治理、RPC、下一代微服务框架... 一文带你彻底搞懂!

    文章每周持续更新,「三连」让更多人看到是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) 单体式应用程序 与微服务相对的另一个概念是传统的单体式应用程序( ...

  5. 面试都在问的「微服务」「RPC」「服务治理」「下一代微服务」一文带你彻底搞懂!

    ❝ 文章每周持续更新,各位的「三连」是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) ❞ 单体式应用程序 与微服务相对的另一个概念是传统的「单体式应用程 ...

  6. 一文带你快速搞懂动态字符串SDS,面试不再懵逼

    目录 redis源码分析系列文章 前言 API使用 embstr和raw的区别 SDSHdr的定义 SDS具体逻辑图 SDS的优势 更快速的获取字符串长度 数据安全,不会截断 SDS关键代码分析 获取 ...

  7. 一文带大家彻底搞懂Hystrix!

    前言? Netflix Hystrix断路器是什么? Netflix Hystrix是SOA/微服务架构中提供服务隔离.熔断.降级机制的工具/框架.Netflix Hystrix是断路器的一种实现,用 ...

  8. .NET Core C#中级篇2-5 常见实用类

    .NETCore CSharp 中级篇2-5 本节内容为常见实用类和方法的使用 String.Format string.format方法是一个字符串格式化类,它里面的一些写法是对字符串进行指定格式的 ...

  9. 零基础学习openstack【完整中级篇】及openstack资源汇总

    1.你是如何学习openstack的?2.你对openstack的组件了解多少?3.你认为openstack该如何学习? 一直想写关于openstack的方面的内容,今天终于整理完成.算是完成一桩心事 ...

随机推荐

  1. kuangbin专题 专题二 搜索进阶 Escape HDU - 3533

    题目链接:https://vjudge.net/problem/HDU-3533 题目分析: 1.人不能经过碉堡; 2.敌军碉堡可能建到我军基地 3.子弹碰到碉堡就没了,说明子弹会被别的城堡给拦截下来 ...

  2. 嵊州D4T1 翻车 rollover 真的翻车了

    翻车 [问题描述] 有一天,小武找到了翻车王,给了他n个整数a1,a2,a3,…an,翻车王需要选择其中的k个数,使得选出的k个数中任意两个的差都可以被m整除. 选出的数可以重复,但不可以超过这n个数 ...

  3. c++学习书籍推荐《C++语言的设计与演化》下载

    百度云及其他网盘下载地址:点我 编辑推荐 <C++语言的设计与演化>由C++语言的设计者Bjarne Stroustrup著就,是一本阐述C++语言的设计及开发过程的无可争辩的内情手册.S ...

  4. .Net Core 学习路由和请求参数传递

    一.配置默认路由方式 {Controller=Home}/{action=Index}/{id?} 默认请求地址:http://localhost:xxx/home/index /id? 是可选项例如 ...

  5. Vue快速学习_第三节

    过滤器 局部过滤器(组件内部使用的过滤器,跟django的很像, filters: {过滤器的名字: {function(val, a,b){}}} 全局过滤器(全局过滤器,只要过滤器一创建,在任何组 ...

  6. 基础篇-1.1走进Java世界

    在走进Java世界之前,我们势必先了解下Java是什么?Java是一门面向对象的编程语言,是静态面向对象编程语言的代表,极好得实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程.Java具有 ...

  7. [原创]MYSQL周期备份shell脚本

    这个脚本是实现阿里云mysql数据库全量周期备份的shell脚本,实现备份数据按一周星期几分开存放.一下是脚本内容: #!/bin/bash echo `date`echo "backup ...

  8. 看MySQL的参数调优及数据库锁实践有这一篇足够了

    史上最强MySQL参数调优及数据库锁实践 1. 应用优化 1.2 减少对MySQL的访问 1.2.1 避免对数据进行重复检索 1.2.2 增加cache层 1.3 负载均衡 1.3.1 利用MySQL ...

  9. 在WebApi项目里使用MiniProfiler并且分析 Entity Framework Core

    在WebApi项目里使用MiniProfiler并且分析 Entity Framework Core 一.安装配置MiniProfiler 在现有的ASP.NET Core MVC WebApi 项目 ...

  10. HTML--网页练习--(360导航首页的一部分)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...