元字符.
几乎能匹配任何字符,除了换行符\n
。但是有时候确实需要匹配“任何字符”,比如在处理HTML源代码时,经常会遇到跨越多行的脚本代码:
<script type="text/javascript">
....
....
</script>
因为这段js代码中出现了换行符,所以.*
的匹配最多只能进行到第一行末尾。之前提到过,可以用类似[\s\S]
的字符组匹配“任意字符”,所以正则表达式<script\s[\s\S]*?</script>
能解决问题。
不过对大多数人来说,点号更加自然,也更简洁,所以正则表达式提供了单行模式。在这种模式下,所有文本似乎只在一行里,换行符是这一行中的“普通字符”,可以由元字符.
匹配。
单行模式对应的模式修饰符是s(Single line),所以如果用模式修饰符,可以在表达式的开头用(?s)
指定,因此上面的表达式也可以改为(?s)<script\s.*?</script>
,效果是一样的。
表5-3 常用语言中单行模式的预定义常量
语言 | 常量 |
---|---|
.NET | RegexOptions.Singleline |
JAVA | Pattern.DOTALL |
JavaScript | 不支持 |
PHP | /regex/s |
Python | re.S re.DOTALL |
Ruby | /regex/m Regex::MULTILINE |
单行模式在不同语言中的称呼很不一样,甚至在同一门语言中也可能有不同的记法(比如python)。
比如在java和python中叫做DOTALL(点号通配),这个名字确实更高明(因为常用模式中还包含“多行模式”,它和“单行模式”没什么关系,但是这两个名字确实很迷惑人)。但是“单行模式”是约定俗成的称呼。
比较奇怪的是ruby的预定义常量Multiline是“多行”的意思,它的模式修饰符也是“m”。这确实让人费解,或许本意是“使用点号.的正则表达式可以跨越多行”?不管怎样,一定要记住,Ruby中的“多行模式”实际上说的是“单行模式”。
网友评论