.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. Spring Cloud Alibaba | Nacos服务中心初探

    目录 Spring Cloud Alibaba | Nacos服务中心初探 1. 什么是Nacos? 1.1 Nacos 1.0 1.2 Nacos 2.0 2. Nacos 架构及概念 2.1 服务 ...

  2. c++学习书籍推荐《C++设计新思维》下载

    百度云及其他网盘下载地址:点我 译序by 侯捷 i 译序by 於春景 iii 目录 v 序言by scott meyers xi 序言by john vlissides xv 前言 xvii 致谢 x ...

  3. sql server编写通用脚本实现获取一年前日期的方法

    问题: 在数据库编程开发中,有时需要获取一年前的日期,以便以此为时间的分界点,查询其前后对应的数据量.例如:1. 想查询截止到一年前当天0点之前的数据量,以及一年前当天0点开始到现在的数据量.2. 想 ...

  4. 【EdgeBoard体验】开箱与上手

    简介 市面上基于嵌入式平台的神经网络加速平台有很多,今天给大家带来是百度大脑出品的EdgeBoard.按照官网文档的介绍,EdgeBoard是基于Xilinx Zynq Ultrascale+ MPS ...

  5. NOIp 2018 普及&提高组试题答案

    你们考的咋样呢?在评论区说出自己的分数吧!

  6. [leetcode] 543. Diameter of Binary Tree (easy)

    原题 思路: 题目其实就是求左右最长深度的和 class Solution { private: int res = 0; public: int diameterOfBinaryTree(TreeN ...

  7. Keil debug command SAVE 命令保存文件的解析

    简介 使用 Keil debug 很方便,把内存中的一段区域 dump 出来也很方便,例如使用命令 SAVE filepath startAddr, endAddr, typeCode .但是要查看 ...

  8. 《PHP从入门到精通(第3版)》目录

    一.基础知识 1.初识PHP 2.PHP环境搭建和开发工具 3.PHP语言基础 4.流程控制语句 5.字符串操作 6.正则表达式 7.PHP数组 8.PHP与Web页面交互 9.PHP与JavaScr ...

  9. 利用TCP协议,实现基于Socket的小聊天程序(初级版)

    TCP TCP (Transmission Control Protocol)属于传输层协议.其中TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送.可靠性.有效流控.全双工操作和多路复用 ...

  10. 林大妈的JavaScript基础知识(三):JavaScript编程(1)对象

    1. 对象的简单介绍与一些注意事项 JavaScript中具有几个简单数据类型:数字.字符串.布尔值.null值以及undefined值.除此之外其余所有值(包括数组.函数,甚至正则表达式)都是对象. ...