正则表达式 第五篇:C# 正则表达式

本文整理C#正则表达式的元字符,正则表达式是由字符构成的表达式,每一个字符表明一个规则,表达式中的字符分为两种类型:普通字符和元字符。普通字符是指字面含义不变的字符,按照彻底匹配的方式匹配文本,而元字符具备特殊的含义,表明一类字符。html

把文本看做是字符流,每一个字符放在一个位置上,例如,正则表达式 “Room\d\d\d”,前面四个字符Room是普通字符,后面的字符\是转义字符,和后面的字符d组成一个元字符\d,表示该位置上有任意一个数字。正则表达式

用正则表达式的语言来描述是:正则表达式 “Room\d\d\d”共捕获7个字符,表示“以Room开头、以三个数字结尾”的一类字符串,咱们把这一类字符串称做一个模式(Pattern),也称做是一个正则。express

一,转义字符

转义字符是\,把普通字符转义为具备特殊含义的元字符,经常使用的转义字符有:ui

  • \t:水平制表符
  • \v:垂直制表符
  • \r:回车
  • \n:换行
  • \\:表示字符 \,也就说,把转义字符 \ 转义为普通的字符 \
  • \":表示字符 ",在C#中,双引号用于定义字符串,字符串包含的双引号用 \" 来表示

二,字符类

在进行正则匹配时,把输入文本看做是有顺序的字符流,字符类元字符匹配的对象是字符,并会捕获字符。所谓捕获字符是指,一个元字符捕获的字符,不会被其余元字符匹配,后续的元字符只能从剩下的文本中从新匹配。spa

经常使用的字符类元字符:code

  • [ char_group]:匹配字符组中的任意一个字符
  • [^char_group]:匹配除字符组以外的任意一个字符
  • [first-last]:匹配从first到last的字符范围中的任意一个字符,字符范围包括first和last。
  • .   :通配符,匹配除\n以外的任意一个字符
  • \w:匹配任意一个单词(word)字符,单词字符一般是指A-Z、a-z和0-9
  • \W:匹配任意一个非单词字符,是指除A-Z、a-z和0-9以外的字符
  • \s:匹配任意一个空白字符
  • \S:匹配任意一个非空白字符
  • \d:匹配任意一个数字字符
  • \D:匹配任意一个非数字字符

注意,转义字符也属于字符类元字符,在进行正则匹配时,也会捕获字符。orm

三,定位符

定位符匹配(或捕获)的对象是位置,它根据字符的位置来判断模式匹配是否成功,定位符不会捕获字符,是零宽的(宽度为0),经常使用的定位符有:htm

  • ^:默认状况下,匹配字符串的开始位置;在多行模式下,匹配每行的开始位置;
  • $:默认状况下,匹配字符串的结束位置,或 字符串结尾的\n以前的位置;在多行模式下,匹配每行结束以前的位置,或者每行结尾的\n以前的位置。
  • \A:匹配字符串的开始位置;
  • \Z:匹配字符串的结束位置,或 字符串结尾的\n以前的位置;
  • \z:匹配字符串的结束位置;
  • \G:匹配上一个匹配结束的位置;
  • \b:匹配一个单词的开始或结束的位置;
  • \B:匹配一个单词的中间位置;

 

四,量词、贪婪和懒惰

量词是指限定前面的一个正则出现的次数,量词分为两种模式:贪婪模式和懒惰模式,贪婪模式是指匹配尽量多的字符,而懒惰模式是指匹配尽量少的字符。默认状况下,量词处于贪婪模式,在量词的后面加上?来启用懒惰模式。对象

  • *:出现0次或屡次
  • +:出现1次或屡次
  • ?:出现0次或1次
  • {n}:出现n次
  • {n,}:出现至少n次
  • {n,m}:出现n到m次

注意,出现屡次是指前面的元字符出现屡次,例如,\d{2} 等价于 \d\d,只是出现两个数字,并不要求两个数字是相同的。要表示相同的两个数字,必须使用分组来实现。blog

五,分组和捕获字符

()  括号不只肯定表达式的范围,还建立分组,()内的表达式就是一个分组,引用分组表示两个分组匹配的文本是彻底相同的。定义一个分组的基本语法:

(pattern)

该类型的分组会捕获字符,所谓捕获字符是指:一个元字符捕获的字符,不会被其余元字符匹配,后续的元字符只能从剩下的文本中从新匹配。

1,分组编号和命名

默认状况下,每一个分组自动分配一个组号,规则是:从左向右,按分组左括号的出现顺序进行编号,第一个分组的组号为1,第二个为2,以此类推。也能够为分组指定名称,该分组称做命名分组,命名分组也会被自动编号,编号从1开始,逐个加1,为分组指定名称的语法是:

(?< name > pattern)

一般来讲,分组分为命名分组和编号分组,引用分组的方式有:

  • 经过分组名称来引用分组:\k<name>
  • 经过分组编号来引用分组:\number

注意,分组只能后向引用,也就是说,从正则表达式文本的左边开始,分组必须先定义,而后才能在定义以后面引用。

在正则表达式里引用分组的语法为“\number”,好比“\1”表明与分组1 匹配的子串,“\2”表明与分组2 匹配的字串,以此类推。

例如,对于 "<(.*?)>.*?</\1>" 能够匹配 <h2>valid</h2>,在引用分组时,分组对应的文本是彻底相同的。

2,分组构造器

分组构造方法以下:

  • (pattern):捕获匹配的子表达式,并为分组分配一个组号
  • (?< name > pattern):把匹配的子表达式捕获到命名的分组中
  • (?:pattern):非捕获的分组,并未分组分配一个组号
  • (?> pattern):贪婪分组

3,贪婪分组

贪婪分组也称做非回溯分组,该分组禁用了回溯,正则表达式引擎将尽量多地匹配输入文本中的字符。若是没法进行进一步的匹配,则不会回溯尝试进行其余模式匹配。

(?> pattern )

4,二选一

| 的意思是或,匹配二者中的任意一个,注意,|把左右两边的表达式分为两部分。

pattern1 | pattern2

六,零宽断言

零宽是指宽度为0,匹配的是位置,因此匹配的子串不会出如今匹配结果中,而断言是指判断的结果,只有断言为真,才算匹配成功。

对于定位符,能够匹配一句话的开始、结束(^ $)或者匹配一个单词的开始、结束(\b),这些元字符只匹配一个位置,指定这个位置知足必定的条件,而不是匹配某些字符,所以,它们被成为 零宽断言。所谓零宽,指的是它们不与任何字符相匹配,而匹配一个位置;所谓断言,指的是一个判断,正则表达式中只有当断言为真时才会继续进行匹配。零宽断言能够精确的匹配一个位置,而不只仅是简单的指定句子或者单词。

正则表达式把文本看做从左向右的字符流,向右叫作后向(Look behind),向左叫作前向(Look ahead)。对于正则表达式,只有当匹配到指定的模式(Pattern)时,断言为True,叫作确定式,把不匹配模式为True,叫作否认式。

按照匹配的方向和匹配的定性,把零宽断言分为四种类型:

  • (?= pattern):前向、确定断言
  • (?! pattern):前向、否认断言
  • (?<= pattern):后向、确定断言
  • (?<! pattern):后向、否认断言

 1,前向确定断言

前向确定断言定义一个模式必须存在于文本的末尾(或右侧),可是该模式匹配的子串不会出如今匹配的结果中,前向断言一般出如今正则表达式的右侧,表示文本的右侧必须知足特定的模式:

 (?= subexpression )

使用前向确定断言能够定一个模糊匹配,后缀必须包含特定的字符:

\b\w+(?=\sis\b)

对正则表达式进行分析:

  • \b:表示单词的边界
  •  \w+:表示单词至少出现一次
  • (?=\sis\b):前向确定断言,\s 表示一个空白字符, is 是普通字符,彻底匹配,\b 是单词的边界。

从分析中,能够得出,匹配该正则表达式的文本中必须包含 is 单词,is是一个单独的单词,不是某一个单词的一个部分。举个例子

Sunday is a weekend day 匹配该正则,匹配的值是Sunday,而The island has beautiful birds 不匹配该正则。

2,后向确定断言

后向确定断言定义一个模式必须存在于文本的开始(或左侧),可是该模式匹配的子串不会出如今匹配的结果中,后向断言一般出如今正则表达式的左侧,表示文本的左侧必须知足特定的模式:

(?<= subexpression )

使用后向确定断言能够定一个模糊匹配,前缀必须包含特定的字符:

(?<=\b20)\d{2}\b

对正则表达式进行分析:

  • (?<=\b20):后向断言,\b表示单词的开始,20是普通字符
  • \d{2}:表示两个数字,数字不要求相同
  • \b:单词的边界

该正则表达式匹配的文本具有的模式是:文本以20开头、以两个数字结尾。

七,用正则从格式化的文本中扣值

有以下的JSON格式的文本,从文本中扣出字段(CustomerId、CustomerName、CustomerIdSource和CustomerType)的值:

{"CustomerDetails":"[{\"CustomerId\":\"57512f19\",\"CustomerName\":\"cust xyz\",\"CustomerIdSource\":\"AadTenantId\",\"CustomerType\":\"Enterprise\"}]"}

注意,该文本转换为C#中的字符时,须要对双引号和转义字符进行转义。因为这四个字段提取规则相同,能够写一个通用的模式来提取:

public static string GetNestedItem(string txt, string key) { string pat = string.Format("(?<=\\\\\"{0}\\\\\":\\\\\").*?(?=\\\\\")", key); return Regex.Match(txt, pat, RegexOptions.IgnoreCase).Value; }

正则表达式得解析:

  • (?<=\\\\\"{0}\\\\\":\\\\\"):后向断言,用于匹配字段名、双引号和冒号
  • .*?:懒惰模式,匹配尽量少的文本
  • (?=\\\\\"):前向断言,用于匹配字段值得双引号

 

注意:对于文本字段是\"abc\",使用C#字符串表示是\\\"abc\\\",这是由于原始字符串 \"是两个字符,所以须要分别表示。

使用正则表达式表示是 \\\\\"abc\\\\\", 这是由于在正则表达式中,\ 是一个转义字符,\\ 表示字符 \ 。

 

 

参考文档:

C#中正则表达式的使用

C# 正则表达式 菜鸟教程

Regular Expression Language - Quick Reference

原文出处:https://www.cnblogs.com/ljhdo/p/11912171.html

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息