拓冰建站拓冰建站
首页 / 资讯中心 / 正文

正则表达式——使用子表达式

使用子表达式1、什么是子表达式2、子表达式3、子表达式的嵌套1、什么是子表达式我们在前面学习了如何匹配一个字符的连续多次重复。正如我们讨论的那样\d将匹配一个或多个数字字符而https?/将匹配http://或https://。在这两个例子里事实上是在我们此前见过的所有例子里​用来表明重复次数的元字符如或*或{2}等等只作用于紧挨着它的前一个字符或元字符。我们来看一个例子。有些短语例如Windows 2000虽然由多个单词构成但其实是一个整体。有许多HTML程序员喜欢让这类短语在浏览器里显示在同一行上。为了确保这一点他们会在编写HTML文档时在这些短语的单词之间使用非换行型空格 , nbsp是“non-breaking space”的缩写其含义是“不是换行符的空格”​而不是普通的空格。下面就是一个这样的例子文本Hello, my name is Bennbsp;Forta, and I am the author of books on SQL, ColdFusion, WAP, Windowsnbsp;nbsp;2000, and other subjects.正则表达式nbsp;{2,}结果nbsp是HTML语言中的非换行空格字符。在这里使用模式nbsp; {2, }的本意是希望它能把nbsp连续两次或更多次的重复出现找出来但它没能给出我们所预期的结果。为什么会这样因为{2, }只作用于紧挨着它的前一个字符——那是一个分号。如此一来这个模式只能匹配像nbsp; ; ; ; ;这样的文本但无法匹配nbsp;nbsp;。2、子表达式这就引出了子表达式的概念。子表达式是一个更大的表达式的一部分把一个表达式划分为一系列子表达式的目的是为了把那些子表达式当作一个独立元素来使用。子表达式必须用(和)括起来。提示和是元字符。如果需要匹配和本身就必须使用它的转义序列\和\​。为了演示子表达式的用法我们来看看刚才的那个例子文本Hello, my name is Bennbsp;Forta, and I am the author of books on SQL, ColdFusion, WAP, Windowsnbsp;nbsp;2000, and other subjects.正则表达式(nbsp;){2,}结果nbsp;是一个子表达式它将被视为一个独立元素而紧跟在它后面的{2, }将作用于这个子表达式不仅仅是分号​。这个模式解决了我们的问题。我们再来看一个例子这次是用一个正则表达式来查找IP地址。IP地址的格式是以英文句号分隔的四组数字例如12.159.46.200。因为每组数字由1个、2个或3个数字字符构成所以这4组数字可以统一使用模式\d{1, 3}来匹配。下面就是这个例子文本Pinging hog.forta.com[12.159.46.200]with32bytesofdata:正则表达式\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}结果\d{1, 3}在这个模式里重复了4次它们分别匹配IP地址里的一组数字。IP地址里的4组数字由分隔该字符由模式里的转义序列\负责匹配。稍微留意一下就会发现在这个例子里模式\d{1, 3}\ .最多3个数字字符、后面跟着一个连续出现了3次它同样可以被表达为一个重复。下面是这个例子的另一种解决方案正则表达式(\d{1,3}\.){3}\d{1,3}结果这个模式与前面那个有着同样的效果但我们这次使用了另一种语法先用和把表达式\d{1, 3}\ 括起来使它成为一个子表达式再用\d{1, 3}\ .{3}把这个子表达式重复了3次它们对应着IP地址里的前3组数字​最后面的\d{1, 3}用来匹配IP地址里的最后一组数字。注意 在上面这个例子里使用\d{1, 3}\ .{4}作为模式是不妥当的。你能分析出为什么不能用它来解决这个问题吗为了提高可读性有不少用户喜欢给表达式的每一个子表达式都加上括号。比如把上面那个例子里的模式写成\d{1, 3}\ .{3}\d{1, 3}​。这种做法在语法上完全成立对表达式的实际行为也没有任何不良影响但视乎具体的正则表达式实现这对匹配操作的速度可能会有点儿影响​。子表达式是一个非常重要的概念所以我们认为有必要再给大家看一个例子它不涉及重复次数问题。在下面的例子里我们的任务是把一条用户记录里的年份数字完整地匹配出来文本ID: 042 SEX: M DOB: 1967-08-17 Status: Active正则表达式19|20\d{2}结果这个例子需要我们构造一个模式去查找一个4位数的年份数字。为了排除没有实际意义的结果我们把前两位数字限定为19和20。这个模式里的|字符是正则表达式语言里的或操作符19|20将匹配数字序列19或20。既然如此模式19|20\d{2}应该匹配以19或20开头的4位数字19或20的后面再跟着两位数字​。可是这个模式的匹配结果与我们的预期并不相符它只匹配到了19随后两位数字没有被匹配到。为什么会这样因为|操作符是把位于它左边和右边的两个部分都作为一个整体来看待的它会把模式19|20\d{2}解释为19或20\d{2}也就是把\d{2}解释为以20开头的那个表达式的一部分​。换句话说它将匹配数字序列19或以20开头的任意4位数字。最终的结果你们已经看到了它只匹配到了19。这个例子的正确答案是把19|20归为一个子表达式如下所示正则表达式(19|20)\d{2}结果我们把所有的选项都归纳到了一个子表达式里这将向|表明我们打算匹配的是这个子表达式里的选项之一。​19|20\d{2}正确地匹配到了1967当然以19或20开头的任何一个4位数字都将与这个模式相匹配。今后比如从现在算起100年内​如果需要修改这段代码以包括以21开头的年份只要把这个模式改成19|20|21\d{2}就可以了。3、子表达式的嵌套子表达式允许嵌套。事实上子表达式允许多重嵌套这种嵌套的层次在理论上没有限制但在实际工作中还是应该遵循适可而止的原则。多重嵌套的子表达式可以构造出功能极其强大的正则表达式来但那难免会让模式变得难以阅读和理解而这也正是很多人觉得正则表达式难以学习和掌握的原因之一。这种表面现象掩盖了这样一个事实绝大多数嵌套子表达式都没有它们看上去那么复杂。为了演示嵌套子表达式的用法我们再去看看刚才那个匹配IP地址的例子。下面是我们刚才使用的模式先是一个连续重复3次的子表达式然后是最后一组数字​文本Pinging hog.forta.com[12.159.46.200]with32bytesofdata:正则表达式(\d{1,3}\.){3}\d{1,3}结果这个模式有什么不对的地方吗从语法上讲它完全正确。IP地址由四组数字构成每组数字由1到3个数字字符构成它们之间以英文句号分隔。说这个模式正确是因为所有合法的IP地址都与之相匹配。但深入研究一下就会发现这个模式还可以匹配其他一些东西说得明白点儿不合法的IP地址也能与之相匹配。IP地址由4个字节构成IP地址中的4组数字分别对应着那4个字节所以IP地址里的每组数字的取值范围也就是单个字节的表示范围即0~255。这意味着IP地址里的每一组数字都不能大于255可是上面那个模式还能匹配诸如345、700、999之类的数字序列而这些数字在IP地址里都是非法的。如果有办法设定各种取值范围的话事情会简单得多但可惜的是正则表达式只是一种工具而且还是一种不懂数学运算的工具它们在匹配字符的时候并不真正关心那些字符到底是什么以及有什么含义。你的数学能力再好在这里也帮不上忙。真的没有解决这个问题的办法吗未必只要你们能够充分发挥你们的逻辑思维能力就能解决与正则表达式有关的任何难题。这里的基本思路是在构造一个正则表达式的时候一定要把你想匹配什么和你不想匹配什么详尽地定义清楚。下面是一个合法的IP地址里的各组数字必须且只能符合的规则我们随后将根据这些规则来构造一个相应的模式任何一个1位或2位数字。任何一个以1开头的3位数字。任何一个以2开头、第2位数字在0~4之间的3位数字。任何一个以25开头、第3位数字在0~5之间的3位数字。像这样把所有的正则全部罗列出来之后构造一个同时符合所有原则的模式的具体步骤也就清晰了。下面是这个例子的继续正则表达式(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))结果这个模式的使用效果显而易见但它还是需要仔细研读才能看明白。这个模式由一系列嵌套子表达式构成。我们先来说说由4个子表达式构成的​​\d{1, 2}|1\d{2}|2[0-4]\d|25[0-5]​\ .:\d{1, 2}匹配任意一位或两位数字0 ~ 99​​1\d{2}匹配以1开头的任意三位数字100 ~ 199​​2[0-4]\d匹配整数200 ~ 249;25[0-5]​匹配整数250 ~ 255。这几个子表达式通过|操作符结合为一个更大的子表达式其含义是只需匹配这4个子表达式之一即可​。随后的\ 用来匹配字符它与前4个子表达式构成的子表达式又构成了一个更大的子表达式4组数字选项和\ .​而接下来的{3}表明需要重复3次。最后数值范围又重复了一次这次省略了尾部的\ .以匹配IP地址里的最后一组数字。通过把4组数字的取值范围都限制在0~255之间这个模式准确无误地做到了只匹配合法的IP地址、不匹配非法的IP地址。上面这个例子里的正则表达式看起来很难理解。把它们弄明白的关键是要把它们分解开、每次只分析和理解一个子表达式。在分析各个子表达式的时候应该按照先内后外的原则来进行而不是从第一个字符开始一个字符一个字符地去尝试。你有过几次这样的经验之后就会发现嵌套子表达式并不像它们看上去那么复杂。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门