




已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第8章 正则表达式第1章 正则表达式本章学习目标 掌握正则表达式语法 掌握正则表达式类 17 简介在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。比如在Windows/Dos下用于文件查找的通配符(wildcard),也就是【*】和【?】。如果想查找某个目录下的所有的Word文档的话,会搜索*.doc。在这里,【*】会被解释成任意的字符串。和通配符类似,正则表达式也是用来进行文本匹配的工具,只不过比起通配符,它能更精确地描述你的需求当然,代价就是更复杂比如可以编写一个正则表达式,用来查找所有以0开头,后面跟着2-3个数字,然后是一个连字号【-】,最后是7或8位数字的字符串(0376-7654321)。1.1 概述.NET Framework SDK 提供了大量的正则表达式工具,使您能够高效地创建、比较和修改字符串,以及迅速地分析大量文本和数据。正则表达式在很多语言中都会用到,其内容几乎是独立于具体语言,因此,本章与其他章节联系不是很大。但这并不意味着正则表达式的用处不大。事实上,正则表达式有着非常广泛的应用。本章主要介绍正则表达式在JavaScript中的应用。正则表达式的英文是regular expression,意思是符合某种规则的表达式,可以将其理解为一种对文字进行模糊匹配的语言。正则表达式用一些特殊的符号(称为元字符)来代表具有某种特征(例如,某一字符必须是数字字符)的一组字符以及指定匹配的的次数,含有元字符的文本不再表示某一具体的文本内容,而是形成了一种文本模式,可以匹配符合该模式的所有文本串。在程序语言中引入正则表达式,可以完成以下功能。 测试字符串的某个模式。例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码或一个身份证号码。这称为数据有效性验证。 替换文本。可以在文档中使用一个正则表达式来标识特定文字,然后全部将其删除,或替换为其他文字。 根据模式匹配从字符串中提取一个子字符串。可以用来在文本或输入字段中查找特定文字。1.1.1 常用正则表达式元素字符转义大多数重要的正则表达式语言运算符都是非转义的单个字符。转义符 【】(单个反斜杠)通知正则表达式分析器反斜杠后面的字符不是运算符。例如,分析器将星号 【*】 视为重复限定符,而将后跟星号的反斜杠 【*】 视为 Unicode 字符 002A。 【a】与响铃(警报)u0007 匹配。 【b】匹配一个单词边界,也就是指单词和空格间的位置。例如:erb 可以匹配never 中的 er,但不能匹配 verb 中的 er。其他还有很多,如:【n】表示换行;【r】表示回车;【t】表示制表符等等。String urlPath=HTmlaademo.html; hello wold lable=sdfkjsdkfjsdflkjrnsdfjkdjflksdjf限定符和限位符表示字符或数字出现的次数以及所在的位置。Abs$ Abstract 【】表示起始位置的字符串。例如:o表示必须以字符o开头。open正确;box错误;Open错误。 【$】表示结束位置的字符串。例如:abc$表示必须以字符串abc结束。Aabc正确;abca错误。 【*】表示重复零次或更多次。例如:a*,所有的字符串都正确,因为可以不出现a字符。 Abce bcdef 【+】表示重复一次或更多次。例如:a+,abcad正确;bcd错误,因为字符a没有出现。abc+,abcde正确;abdce错误,因为字符串abc没有出现。 【?】表示重复零次或一次。 【n】表示重复n次。例如:o2,food正确;box错误,因为o只出现一次;foodBox正确,匹配food中的2个o。 【n,】表示重复n次或更多次。 【n,m】表示重复n到m次。a-z+$0-98$重庆座机:023-60-97$12K 1 2 K字符类字符类表示一组可以匹配输入字符串的字符。组合原义字符、转义符和字符类以构成正则表达式模式。 【.】表示匹配除换行符【n】以外的任意字符。 【char】(正字符分组)匹配指定字符分组内的任何字符。例如: abc,表示小写abc中的任意一个字符。a正确;d错误。 【char】(负字符分组)匹配不在指定字符分组内的任何字符。例如: abc,表示不是小写abc中间的任意一个字符。d正确;a错误。 【char-char】(字符范围)匹配字符范围中的任何字符。例如:a-z,表示小写的a-z之间的任意一个字符。a正确;A错误。 【w】表示匹配任意一个单词字符。等同于a-zA-Z_0-9。例如:w,A正确;错误。 【W】表示不匹配任意一个单词字符。等同于a-zA-Z_0-9。例如:W,正确;A错误。 【d】表示一个十进制数字。等同于0-9。 【D】表示一个非十进制数字。等同于0-9。 【s】表示匹配任意空白符的字符。 【S】表示匹配任意不是空白符的字符。w+(-+.w+)*w+(-.w+)*.w+(-.w+)*w+(-+.w+)*w.(com)|cn|eduXhsnhd+fdgdfgqq.qqq.qqqq.q分支条件正则表达式里的分支条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用【|】把不同的规则分隔开。例如:(a-n|O-Z),表示只能以小写的a-n或者大写的O-Z开头。Book错误;book正确;open正确;Open正确。使用分支条件时,要注意各个条件的顺序。匹配分支条件时,将会从左到右地测试每个条件,如果满足了某个分支的话,就不会去再管其它的条件了。例如:将刚才的正则表达式中的括号去掉,a-n|O-Z,就会表示以小写的a-n开头或包含大写的O-Z。1.1.2 Capture、Match、MatchCollectionCapture表示表示单个子表达式捕获中的结果。拥有Index、Length、Value属性。Match类表示正则表达式匹配操作的结果。Match类无法进行实例化,需要从Regex类中产生。继承于Capture类。MatchCollection表示通过以迭代方式将正则表达式模式应用于输入字符串所找到的成功匹配的集合。该集合为不可变(只读)的,并且没有公共构造函数。MatchCollection的实例是由Regex.Matches方法返回的。Match类的常用方法和属性:GroupCollection Groups属性:获取由正则表达式匹配的组的集合。int Index属性:原始字符串中根据正则表达式发现捕获的子字符串的第一个字符的位置。例如:字符串abcd经过bcd匹配后,Match对象返回的Index就是1。int Length属性:根据正则表达式捕获的子字符串的长度。例如:字符串abcd经过bc匹配后,Match对象返回的Length就是2。Match NextMatch()方法:从上一个根据正则表达式匹配结束的位置(即在上一个匹配字符之后的字符)开始返回一个包含下一个匹配结果的新Match。例如:字符串abcd经过ab匹配后,返回的Match就是从b开始匹配的结果。bool Success属性:判断正则表达式匹配是否成功。string Value属性:获取根据正则表达式匹配捕获的子字符串。例如:字符串abcd经过ab匹配后,结果为a。1.1.3 Regex类Regex类表示不可变(只读)正则表达式类。它还包含各种静态方法,允许在不显式创建其他类的实例的情况下使用其他正则表达式类。构造函数中需要一个正则表达式作为参数。下面的代码示例演示如何使用正则表达式检查字符串是否是整型数字。代码:1. Regex regex = new Regex(-?1-9d*$);2. string arr = new string 23, -43, -54.8, a1df, 123.3 ;3. foreach (string str in arr)4. 5. Console.WriteLine(str + (regex.IsMatch(str) ? 是 : 不是) +整型);6. 第1行:正则表示式为判断一个字符串是否是整数,包含0或1个【-】号,第一位数字不能是0,不包含非数字字符,以数字结尾。第5行:利用IsMatch方法判断该字符串是否匹配正则表示式,匹配的输出“是”,否则输出“不是”。结果下面的代码示例演示如何使用正则表达式检查字符串并获取相应的信息。代码:Regex regex = new Regex(W|_)w2);string content = test_;foreach (Match match in regex.Matches(content)Console.Write(开始下标: + match.Index);Console.Write(t值: + match.Value);Console.WriteLine(t下一个匹配: + match.NextMatch().Value);上述代码中的正则表达式声明了,匹配特殊字符或【_】,再加2个单词字符的字符串。结果:1.1.4 分组我们学习了怎么重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复多个字符又该怎么办?可以用小括号来指定子表达式(也叫做分组),然后就可以指定这个子表达式的重复次数了,也可以对子表达式进行其它一些操作。例如:要求为一个软件设计生日的正则表达式,能匹配1900.01.01-2050.12.31的日期。首先分析,整个的正则表达式应该4个年份数字+【.】+2个数字+【.】+2个数字。然后设计年份,12d3,这个设计说明是首位是1或2,然后是3位数字,但是存在缺陷,因为可能会产生1000或2999年。因此,首先判断如果是19XX年,说明后面2个数字可以任意安排;如果是20XX年,则需要第3位只能是0-5,但是如果第3位是5的话,则第4位又只能是0。最后结果年份的正则表达式为:(19d2)|(20(0-4d)|(50)。接着设计月份和日期,由于月份和日期是同步的,所以要一起设计,因为每个月的天数不一样。(这里暂时不考虑闰年平年的问题,将2月均设为28天,否则的分组量会急剧加大)。首先判断月份如果是0X,则第2位可以任意;如果是1X,则第2位只能是0-2之间。而天数则是0X、1X、20-28、30-31多种情况,因此此处判断分组较多。如果该月是31天的则:(013578)|(101).(01-9)|(12d)|(301)。如果该月是30天的则:(0469)|(11).(01-9)|(12d)|(30)。如果该月是28天的则:02.(01-9)|(1d)|(20-8)。最后生日的正则表达式为:(19d2)|(20(0-4d)|(50).(013578)|(102).(01-9)|(12d)|(301)|(0469)|(11).(01-9)|(12d)|(30)|02.(01-9)|(1d)|(20-8)$。由于正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择,字符类来描述。1.1.5 Group类和GroupCollection类Group 表示单个捕获组的结果。一个捕获组可以在单个匹配中捕获零个、一个或更多的字符串,因此 Group 提供 Capture 对象的集合。Group继承与Capture类。表示捕获组的集合。GroupCollection 返回单个匹配中的捕获组的集合。下列获取匹配后的分组结果。代码:Regex regex = new Regex(W|_)w2);string content = test_;foreach (Match match in regex.Matches(content)GroupCollection groups = match.Groups;foreach (Group group in groups)Console.Write(group.Value + t);Console.WriteLine();结果:1.2 高级应用以下是正则表达式的一些高级特性。1.2.1 后向引用使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。后向引用的常用语法: 【(exp)】表示匹配exp,并捕获文本到自动命名的组里 【(?exp)】表示匹配exp,并捕获文本到名称为name的组里,也可以写成【(?nameexp)】 【(?:exp)】表示匹配exp,不捕获匹配的文本,也不给此分组分配组号。后向引用用于重复搜索前面某个分组匹配的文本。例如: b(w+)bs+1b,表示由小括号内组成的是整个单词,因为被包括在一对b中,然后有1到多个的空格符,后面1引用了前面括号内的w+单词。go go正确;go goHome错误,因为第二个go应该是结束的。 this(siss)w+(Collection);that1w+2,这个表达式中,1引用了第一个小括号内的siss,2引用了第二个小括号内的Collection,this is MatchCollection;that is GroupCollection正确匹配。以下示例提供了反向引用的操作。代码:string x1 = Live for nothing,die for something;string y1 = Live for nothing,die for somebody;Regex regex = new Regex(Live(sa-z3s)no(a-z5),die1some2$);Console.WriteLine(x1匹配数量: + regex.Matches(x1).Count);Console.WriteLine(y1匹配数量: + regex.Matches(y1).Count);Console.WriteLine();/正则表达式引擎会记忆【()】中匹配到的内容,作为一个【组】,并且可以通过索引的方式进行引用。表达式中的【1】,用于反向引用表达式中出现的第一个组,即粗体标识的第一个括号内容,【2】则依此类推。string x2 = Live for nothing,die for something;regex = new Regex(Live(sa-z3s)no(a-z5),die1some2$);if (regex.IsMatch(x2)Console.WriteLine(组0的值为: + regex.Match(x2).Groups0.Value); Console.WriteLine(组1的值为: + regex.Match(x2).Groups1.Value + 注意两边的空格);Console.WriteLine(组2的值为: + regex.Match(x2).Groups2.Value); Console.WriteLine();/获取组中的内容。注意,此处是Groups1,因为Groups0是整个匹配的字符串,即整个变量x的内容。string x3 = Live for nothing,die for something;regex = new Regex(Live(sa-z3s)no(?a-z5),die1some2$);if (regex.IsMatch(x3)Console.WriteLine(组0的值为: + regex.Match(x2).Groups0.Value);Console.WriteLine(组1的值为: + regex.Match(x2).Groups1.Value);Console.WriteLine(组2的值为: + regex.Match(x2).Groups2.Value); Console.WriteLine(组g1的值为: + regex.Match(x3).Groupsg1.Value);Console.WriteLine();/可根据组名进行索引。string x4 = Live for nothing nothing;regex = new Regex(a-z+) 1);if (regex.IsMatch(x4)x4 = regex.Replace(x4, $1);Console.WriteLine(使用组索引删除后的新值为: + x4);Console.WriteLine();/删除原字符串中重复出现的【nothing】。在表达式之外,使用【$1】来引用第一个组。string x5 = Live for nothing nothing;regex = new Regex(?a-z+) 1);if (regex.IsMatch(x5)x5 = regex.Replace(x5, $g1);Console.WriteLine(使用组名删除后的新值为: + x5);Console.WriteLine();/删除原字符串中重复出现的【nothing】。在表达式之外,使用【$组名】来引用组。string x6 = Live for nothing;regex = new Regex(Live for no(?:a-z5)$);if (regex.IsMatch(x6)Console.WriteLine(使用非捕获组后组1的值为: + regex.Match(x6).Groups1.Value);Console.WriteLine();/在组前加上【?:】表示这是个“非捕获组”,即引擎将不保存该组的内容。结果:1.2.2 贪婪与懒惰正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。例如:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。例如:a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。代码:string x = Live for nothing,die for something;Regex regex = new Regex(.*thing);if (regex.IsMatch(x)Console.WriteLine(贪婪匹配: + regex.Match(x).Value);regex = new Regex(.*?thing);if (regex.IsMatch(x)Console.WriteLine(懒惰匹配: + regex.Match(x).Value);结果:1.2.3 回溯与非回溯由于正则表达式引擎的贪婪特性,导致它在某些情况下,将进行回溯以获得匹配。因此使用【(?)】方式进行强制性非回溯声明。代码:string x = Live for nothing,die for something;Regex regex = new Regex(.*thing,);if (regex.IsMatch(x)Console.WriteLine(匹配结果: + regex.Match(x).Value);/输出:Live for nothing,Console.WriteLine();/【.*】由于其贪婪特性,将一直匹配到字符串的最后,随后匹配thing,但在匹配,时失败,此时引擎将回溯,并在thing, 处匹配成功。regex = new Regex(?.*)thing,);if (regex.IsMatch(x)/不匹配Console.WriteLine(匹配结果: + regex.Match(x).Value);elseConsole.WriteLine(强制非回溯后匹配失败。);/由于使用【?】强制非回溯,所以整个表达式匹配失败。结果:1.2.4 正、反向预搜索通过匹配或不匹配进行搜索。正向预搜索表示需要匹配XXXX之后。 正声明:使用【(?=exp)】,声明exp作为最终匹配结果的条件。 负声明:使用【(?!exp)】,声明exp不作为最终匹配结果的条件。代码:string x = 1MB = 1024KB;Regex regex = new Regex(d+(?=MB);if (regex.Matches(x).Count = 1)Console.WriteLine(正向正声明: + regex.Match(x).Value);/正向正声明表示必须保证在数字的后面必须紧跟着MBregex = new Regex(d+(?!MB);if (regex.Matches(x).Count = 1)Console.WriteLine(正向负声明: + regex.Match(x).Value);/正向负声明表示数字之后不能跟有“MB”。结果:反向预搜索表示需要匹配XXXX之前。 正声明:使用【(?=exp)】,声明exp作为最终匹配结果的条件。 负声明:使用【(?!exp)】,声明exp不作为最终匹配结果的条件。代码:string x = MB:1 = KB:1024;Regex regex = new Regex(?=MB:)d+);if (regex.Matches(x).Count = 1)Console.WriteLine(反向正声明: + regex.Match(x).Value);/输出:1024/反向正声明表示在数字之前必须紧跟着MB:regex = new Regex(?!MB:)d+);if (regex.Matches(x).Count = 1)Console.WriteLine(反向负声明: + regex.Match(x).Value); /输出:2048/反向负声明表示在数字之前必须紧跟
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 江苏省徐州市新沂市2021-2022学年五年级上学期科学期中试卷(含答案)
- 民法典的新变化
- 江苏省连云港市赣榆区2026届化学高一第一学期期末联考模拟试题含解析
- 2026届湖北随州市普通高中化学高一上期中达标检测模拟试题含解析
- 2025年考研英语(一)长篇阅读技巧提升与押题卷
- 2025年注册电气工程师考试试卷 电气设计专项训练:电气工程设计与施工协调
- 2025年注册土木工程师考试真题试卷 建筑结构设计专项训练
- 2025年高考英语阅读理解专项训练:长篇阅读技巧揭秘
- 星光学校开展校园安全生产大排查大整治行动自查自纠报告
- 测量员岗位职责是什么
- 海关退运协议书
- 新八德教育工作计划、总结模版
- 电梯、自动扶梯和自动人行道随行文件编制说明
- 学校捐款协议书范本
- 车间标签标识管理制度
- 农田托管合同样本
- 部编版小学语文一年级上册教案 全册
- 医院医用织物洗涤规范
- 金氏五行升降中医方集
- 银行业金融机构绩效考评监管指引
- 血液透析中出血的原因及预防
评论
0/150
提交评论