正则指引之匹配模式

前端之家收集整理的这篇文章主要介绍了正则指引之匹配模式前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

所谓匹配模式(match mode),指的是匹配时使用的规则。设置特定的模式,可能会改变对正则表达式的识别,也可能会改变正则表达式中字符的匹配规定。常用的匹配模式一共有4种:不区分大小写模式单行模式多行模式注释模式

不区分大小写模式

在看这个模式的应用实例之前,必须首先了解模式的指定方式。通常,有两种办法指定匹配模式以模式修饰符指定,或者以预定义的常量作为特殊参数传入来指定。模式修饰符即模式对应的单个字符,使用时将其填入特定结构(?modifier)中(其中的modifier为模式修改),嵌在正则表达式的开头。比如不区分大小写的匹配模式对应的模式修饰符 i (case Insensitive),对 the 指定此模式,完整的正则表达式就是 (?i)the 。另一种指定模式的方式是使用预定义的常量作为参数,传入正则函数。在Java中,属于Pattern类。下表展示了常用语言中不区分大小写模式的预定义常量:

语言
常量
.NET
RegexOptions.IgnoreCase
Java
Pattern.CASE_INSENSITIVE
JavaScript
/regex/i
PHP
/regex/i
Python
re.I
re.IGNORECASE
Ruby
Regexp::IGNORECASE
/regex/i

以Java为例:

//不区分大小写模式
Stringtext1="aaaAAAaaaaaAAAA";
Patternp1=Pattern.compile("\\b(a{3,5})\\b",Pattern.CASE_INSENSITIVE);
Matcherm1=p1.matcher(text1);
while(m1.find()){
System.out.println(m1.group(1));
}
//不区分大小写模式(使用模式修饰符)
Stringtext1="aaaAAAaaaaaAAAA";
Patternp1=Pattern.compile("(?i)\\b(a{3,5})\\b");
Matcherm1=p1.matcher(text1);
while(m1.find()){
System.out.println(m1.group(1));
}

单行模式

元字符点号(.几乎能匹配任何字符,唯有换行符 \n 是例外。但是,有时候确实需要匹配“任何字符”,比如在处理HTML源代码时,经常会遇到跨越多行的脚本代码

<scripttype="text/javascript">
...code....
...code....
</script>

正则文档里一般都会说明“点号不能匹配换行符”,不过许多人并不习惯仔细阅读文档,所以认为点号 . 能匹配任何字符,当然也就包括换行符,所以直接的想法是用<script\s.*?</script>来匹配。接下来你就会发现最多只能进行到第一行末尾。之前提到过,可以用[\s\S]之类的字符组匹配“任意字符”,所以正则表达式<script\s[\s\S]*?</script>能解决问题。

不过对大多数人来说,点号更加自然,也更简洁,所以正则表达式提供了单行模式。在这种模式下,所有文本似乎只在一行里,换行符是这一行中的“普通字符”,所以可以由点号 . 匹配。单行模式对应的模式修饰符s (Single line),所以如果用模式修饰符,可以在表达式的开头用(?s)指定:

//单行模式(使用模式修饰符)
Stringtext1="<scripttyte='text/javascript'>dddddddddd\r\nrrrrrrrrrrrr</script>";
Patternp1=Pattern.compile("(?s)<script\\s.*?</script>");
Matcherm1=p1.matcher(text1);
while(m1.find()){
System.out.println(m1.group());
}
//单行模式(使用叁数)
Stringtext1="<scripttyte='text/javascript'>dddddddddd\r\nrrrrrrrrrrrr</script>";
Patternp1=Pattern.compile("<script\\s.*?</script>",Pattern.DOTALL);
Matcherm1=p1.matcher(text1);
while(m1.find()){
System.out.println(m1.group());
}

常用语言中单行模式的预定义常量:

常量
.NET
RegexOptions.Singleline
Pattern.DOTALL
JavaScript
不支持此模式
PHP
/regex/s
Python
re.S
re.DOTALL
Ruby
Regexp::MULTILINE
/regex/m

你可能注意到了,单行模式在不同语言中的称呼很不一样。比如在Java和Python中叫 DOTALL(也就是点号通配),这个名字确实更高明。不过,“单行模式”成了约定俗成的称呼。

多行模式

单行模式影响的是点号的匹配规则:在默认模式下,点号 . 可以匹配除换行符之外的任何字符,在单行模式下,点号 . 可以匹配包括换行符在内的任何字符;多行模式影响的是^和$的匹配规则:在默认模式下,^和$匹配的是整个字符串的起始位置和结束位置,但在多行模式下,它们也能匹配字符串内部某一行文本的起始位置和结束位置。

假设,需要找到下面文本中所有数字字符开头的行:

1 line

NO digit

2 line

解决这个问题,需要定位到每行的起始位置,尝试匹配一个数字字符,如果成功,则匹配之后的整行文本。多行模式的模式修饰符 m (Multiline),所以在表达式的开头用(?m)指定多行模式,这样^可以定位到字符串内部每一行的起始位置;匹配数字字符的表达式是 \d ,因为没有指定单行模式,点号 . 不能匹配换行符,.*可以匹配“之后的整行文本”,整个表达式就是 (?m)^\d.* 。示例:

//多行模式(使用修饰符)
Stringtext1="1line\r\nNodigit\r\n2line";
Patternp1=Pattern.compile("(?m)^\\b\\d+\\b");
Matcherm1=p1.matcher(text1);
while(m1.find()){
System.out.println(m1.group());
}
//多行模式(使用参数)
Stringtext1="1line\r\nNodigit\r\n2line";
Patternp1=Pattern.compile("^\\b\\d+\\b",Pattern.MULTILINE);
Matcherm1=p1.matcher(text1);
while(m1.find()){
System.out.println(m1.group());
}

下表列出常用语言中预定义常量的写法:

常量
.NET
RegexOptions.Multiline
Pattern.NULTILINE
JavaScript
/regex/m
PHP
/regex/m
Python
re.M
re.MULTILINE
Ruby
默认即为多行模式

注释模式

有时,用到的正则表达式可能非常复杂,不但难以编写和阅读,也难以维护。如果正则表达工也像程序源代码一样,可以添加注释,阅读和维护就容易多了。为了解决这个问题,许多语言支持使用 (?#comment)的记法添加注释,comment就是注释的内容。所以,这样的表达式:^\d.*?$,就可以写成这样:

^(?#start of the line)\d(?#digit).*(?#sest of the line)

.NET,Python,Ruby,PHP支持这种记法,Java与javascript则不支持

原文链接:https://www.f2er.com/regex/360819.html

猜你在找的正则表达式相关文章