什么是正则表达式?正则表达式,又称正则表达式和正则表达式(英语:正则表达式,在代码中常缩写为regex、regexp或re),是计算机科学的一个概念。正则表达式使用单个字符串来描述和匹配一系列符合特定语法规则的字符串。它被用于几乎所有类型的计算机编程语言。它可以分为普通正则表达式、扩展正则表达式和高级正则表达式。linux shell中通常使用普通的正则表达式,而高级正则表达式语法规范基本上是从perl演变而来的。目前常见的编程语言(php、perl、python、java、c#)都支持高级正则表达式。
为什么要学习正则表达式?高级编程语言中的正则表达式几乎都是从perl开发的,所以语法几乎是一样的。你学得很好,一种正则表达式语言。它可以用于几乎所有的编程语言。比如,我知道sql语法、后端mysql、mssql几乎是通用的。这也是我们需要学好正则表达式的一个原因,也就是普适性。另一个原因是正则表达式强大的文本匹配功能。很多文本匹配处理没有正则表达式真的很难。例如,从字符串中读出手机号码的格式。如果用字符串搜索,需要做一个循环,写一个判断。这需要大量的代码和开发时间。如果使用正则表达式,只需一行代码就可以了。匹配所有对:html标记。如果我们想这样做,我们会发现它非常复杂。我们需要处理级别和匹配标签。一般人不可能在几个小时内完成。如果使用正则表达式,只需要几分钟。
正则表达式的字符串格式既然我们知道正则表达式的重要性和普遍性。然后我们可以了解常见的格式。常规正则表达式是由普通字符和特殊字符(元字符)组成的字符串。例如,匹配“ab”,后跟数字字符串“abd”,其中ab是普通字符,d代表0-9位数字,这意味着前面的字符可以出现一次或多次。哈哈,好像真的很容易!
正则表达式是普通的、扩展的或高级的正则表达式。差异,特殊字符可能会有一些差异。许多特殊字符可以组合起来形成一套新的匹配规则。这里我就不说太深了。一般来说,我们只需要知道它的公共元字符。基本上可以写正则表达式。
以下是javascript正则表达式的常见元字符:
字符描述将下一个字符标记为特殊字符、文字字符、向后引用或八进制转义字符。例如,“n”与字符“n”匹配。“n”匹配新的行字符。序列“ ”匹配“”和“”(“匹配“(”)。匹配输入字符串的起始位置。如果设置了RegExp对象的Multiline属性,它也匹配“ n”或“ r”之后的位置。$匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“ n”或“ r”之前的位置。*匹配前面的子表达式零次或多次。例如,zo*可以匹配“z”和“zoo”。*相当于{0,}。将前面的子表达式匹配一次或多次。例如,“zo”可以匹配“zo”和“zoo”,但不能匹配“z”。相当于{1,}。匹配前面的子表达式零次或一次。例如,做什么?您可以在“do”或“does”中匹配“do”。相当于{0,1}。{n} n是非负整数。匹配n次。例如,“o{2}”不能匹配“Bob”中的“o”,但可以匹配“food”中的两个o。{n,} n是非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但可以匹配“foooood”中的所有o。“O{1,}”相当于“o”。“O{0,}”相当于“o *”。{n,m} m和n为非负整数,其中n=m,至少匹配n次,最多匹配m次。刘的o{1,3}将与fooooood中的前三个o相匹配。O{0,1}相当于“o”。请注意,逗号和两个数字之间不能有空格。当该字符后跟任何其他分隔符(*,{n},{n,},{n,m}),匹配模式不贪心。非贪婪模式尽可能少地匹配搜索到的字符串,而默认贪婪模式尽可能多地匹配搜索到的字符串。例如,对于字符串“oooo”,“o?将匹配单个“o”,而“o”将匹配所有“o”。匹配除“n”以外的任何单个字符。若要匹配包括“ n”在内的任何字符,请使用像“[”这样的模式。 n]'。(pattern)匹配该模式并获得该匹配。获得的matches可以从生成的Matches集合中获得,该集合在VBScript中使用,在JScript中使用$0…$9属性。若要匹配括号字符,请使用“(”或“”)。(?pattern)匹配模式但没有获得匹配结果,也就是说,它是一个未获得的匹配,不会被存储以备将来使用。当使用“或”字符(|)来组合模式的各个部分时,这很有用。例如,' ' industr tr(?y|ies)是比“industry|industries”更简单的表达。(?=pattern),匹配任何字符串匹配模式开头的搜索字符串。这是非采集匹配,也就是说,该匹配不需要采集以备后用。例如,' ' Windows(?=95|98|NT|2000)可以匹配“Windows 2000”中的“Windows”,但不能匹配“Windows 3.1”中的“Windows”。预搜索不消耗字符,也就是说,在匹配发生后,对下一个匹配的搜索会在最后一个匹配后立即开始,而不是在包含预搜索字符后开始。(?模式),匹配任何不匹配的字符串开头的搜索字符串在字符串不匹配模式的任何点匹配搜索字符串。这是非采集匹配,也就是说,该匹配不需要采集以备后用。例如Windows(?95|98|NT|2000)可以匹配“Windows 3.1”中的“Windows”,但不能匹配“Windows 2000”中的“Windows”。预搜索不消耗字符,也就是说,匹配发生后,立即开始搜索最后一个匹配后的下一个匹配,而不是在包含预搜索字符后开始x|y匹配x或y。例如,“z|food”可以匹配“z”或“food”。(z|f)ood '匹配“缩放”或“食物”。[xyz]字符集。匹配任何一个包含的字符。
例如,'[ABC]'可以在' plain '中匹配' a '。[XYZ]一组负面人物。匹配任何未包含的字符。例如,'[ABC]'可以与' plain '中的' p '匹配。[a-z]字符范围。匹配指定范围内的任何字符。例如,'[a-z]'可以匹配“a”到“z”范围内的任何小写字母字符。[a-z]负字符范围。匹配不在指定范围内的任何字符。例如,'[a-z]'可以匹配“a”到“z”范围之外的任何字符。b匹配单词边界,即单词和空格之间的位置。例如,“erb”可以在“never”中匹配“er”,但不能在“er b”中匹配“er”。'匹配非单词边界'“ErB”可以匹配“动词”中的“Er”,但不能匹配“never”中的“er”。cx匹配x指示的控制字符。例如,cM匹配控制-M或回车。x的值必须是a-z或A-Z之一.否则,c被认为是一个原始的c字符。d匹配一个数字字符。相当于[0-9]。D匹配一个非数字字符。相当于[0-9]。f匹配分页符。相当于x0c和cL。 n匹配新的行字符。相当于x0a和cJ。r匹配回车符。相当于x0d和cM。s匹配任何空白字符,包括空格、制表符、分页符等。相当于[fnrtv]。S匹配任何非空白字符。相当于[ f n r t v]。 t匹配选项卡。相当于x09和cI。v匹配垂直制表符。相当于x0b和cK。 w匹配任何单词字符,包括下划线。相当于“[a-za-z0-9 _]”。 w匹配任何非单词字符。相当于“[a-za-z0-9 _]”。xn匹配n,其中n是十六进制转义值。十六进制转义值的长度必须是两位数。例如,“匹配”a。x041 '相当于' x04'' 1 '。ASCII编码可以用在正则表达式中。num匹配num,其中num是正整数。对获得的匹配的引用。例如,'(。)1 '匹配两个连续的相同字符。n标识八进制转义值或向后引用。如果在n之前至少有n个获得的子表达式,则n是向后引用。否则,如果n是八进制数(0-7),则n是八进制转义值。nm标识八进制转义值或反向引用。如果nm前面至少有一个tnm子表达式,则nm是一个反向引用。如果在nm之前至少有n个采集,则n是后跟单词m的后向引用。如果不满足前面的条件,如果n和m都是八进制数(0-7),nm将匹配八进制转义值nm。nml如果n是八进制数(0-3),m和l都是八进制数(0-7),则匹配八进制转义值nml。 n取消匹配,其中n是由四个十六进制数字表示的Unicode字符。例如,u00A9与版权符号(?)。从上面的元字符中,我们可以看到很多元字符实际上可以代表一组普通字符。所以我们要匹配一些字符串,正则表达式的种类往往很多。比如[0-9], d,[0123456789]可以用来匹配0-9个数字,所以三个都可以用,条条大路通罗马,没错。那么哪个正则表达式更好,性能更高,匹配速度更快呢?通过10万轮匹配,发现几种之间几乎没有区别。d比[0-9]快,[0-9]比[0123456789]快。d就正则表达式简化程度而言是最简单的。当我们使用它时,我们试图用元字符来表示字符集。而且速度快!
正则表达式怎么写?我们写正则表达式的时候,先从分析匹配字符串的特征开始,然后逐步补充其他元字符和普通字符。从左到右匹配。
例如,我们需要匹配一个手机号码。
1.分析字符串特征,手机号是一个数字,以1开头,长11位。
2.您可以在1的开头写“1 d”,后跟数字,也可以是:1[0-9]。
3.数字长度为11位,继续添加1d{10}。以下数字长度为11个字符,也可以是:1[0-9]{ 10 };{}中数字表示其左边的字符可以重复的次数。
4.所有字符必须是11位数字,所以头尾必须直接满足条件,所以可以是:1 d {10} $。
比如我们匹配QQ号。
1.分析QQ号的特点是号码至少是5位数,第一个字符不是0,最大长度现在是11位数。
2.可以先定义第一个字符。[1-9]d第一个字符是1到9,后面是字符。
3.以下字符的数量为4到10位数[1-9]d{4,10}。
4.所有字符串都必须满足上述匹配,因为它们可以写成:[1-9] d {4,10}。
示例:匹配IP地址。
1.ip结构分析是每段0-255,中间段用“.”划分,共4节。
2.首先我们写第一个0-255,可以分为0-9个一位数,10-99个两位数,100-199个三位数,200-249个三位数,第二节,250-255的第四节。
[0-9]|[1-9][0-9]| 1[0-9]{ 2 } | 2[0-4][0-9]| 25[0-5]“|”表示计算优先级最低,左右两边可以是多个元字符。
3.这个字符用“.”重复三次中间,所以结果是:
[0-9] | [1-9] [0-9] | 1 [0-9] {2} | 2 [0-4] [0-9] | 25 [0-5] .这样可以吗?我们发现有一个问题。“|”的优先级最低,它将组合最后一个。字符列表变成“25[0-5] ”。因此,它应该是第一个后跟“.”的情况字符,正确如下:([0-9]|[1-9][0-9]| 1[0-9]{ 2 } | 2[0-4][0-9]| 25[0-5])。我们会发现,其实每个()字符都有一个子匹配,匹配结果中会出现()内容。这里添加()的目的是为了优先计算,所以不需要匹配里面的内容。我们可以添加和忽略匹配的内容字符:3360,结果会变成:(?[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).
4.一个段落已经匹配,然后我们需要重复三次。我们可以直接重复前面的表达式三次:
方法1:(?[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).(?[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).(?[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).
方法二:以第一段为一组,重复三遍(?3360 [0-9] | [1-9] [0-9] | 1 [0-9] {2} | 2 [0-4] [0-9] | 25 [0-5]) .){3},然后匹配结果也会被忽略,可以改为。
(?(?3360 [0-9] | [1-9] [0-9] | 1 [0-9] {2} | 2 [0-4] [0-9] | 25 [0-5]) .){3}哈哈,看到这个表情是不是头晕?这利用了重复的次数,大大简化了结果。
5.最后是0-255的比赛。
(?(?[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}(?3360[0-9]|[1-9][0-9]| 1[0-9]{ 2 } | 2[0-4][0-9]| 25[0-5]),也就是在后面再加一个0-255匹配,然后在上面加。(?[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}(?[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
下图是读取一段文字中的所有IP格式地址。
其中(?=.)是正匹配,搜索左边的字符串,而右边的字符串必须满足?=只有后来匹配成功的才会匹配成功!
好了,写了几个例子,发现一口气就能从一个简单的正则表达式匹配出这么长的表达式。我觉得有点头晕。事实上,从简单的正则表达式中获得长正则表达式并不奇怪。逐渐补充。欢迎讨论交流!