先尝试执行以下代码:println("play\nscala".matches(".*"))你没看错,打印结果为假。与键盘布局一样,这是由于一个历史问题。早期的正则表达式工具根据行处理文本,因此.匹配除换行符以外的任何字符。大多数编程语言在设计正则表达式时都遵循这一传统,但提供了一个选项来启用“点匹配换行符”模式。Java提供了两种方式来启用“点匹配换行符”模式。第一种方式是在构造Pattern对象时指定匹配方式:valp=Pattern.compile(".*",Pattern.DOTALL)println(p.matcher("play\nscala").matches())//true另一种方式是在正则表达式的开头指定嵌入模式修饰符(embeddedmodemodifier),这也是一种更通用的方式:println("play\nscala".matches("(?s).*"))//truePattern.DOTALL和(?s)是等价的。Java中常用的匹配模式如下:1)Pattern.DOTALL开启dotall模式。在dotall模式下,.模式中的匹配任何字符,包括换行符。默认情况下(即没有启用dotall模式),.不匹配换行符。相当于修饰符(?s)。valp=Pattern.compile(".*",Pattern.DOTALL)valm=p.matcher("play\nscala")println(m.matches())//输出true2)Pattern.MULTILINE开启多行匹配模式.在多行匹配模式下,模式中的^和$会逐行匹配每一行的开头和结尾。默认情况下(即未启用多行匹配模式),^和$将匹配整个字符串的开头和结尾。相当于修饰符(?m)。valp=Pattern.compile("^.*$",Pattern.MULTILINE)valm=p.matcher("play\nscala")while(m.find()){println("find:"+m.group(0))}//输出find:playfind:scala3)Pattern.UNIX_LINES启用Unix换行模式,用“\n”标记每行的结束,相当于修饰符(?d)。valp=Pattern.compile("^.*$",Pattern.UNIX_LINES|Pattern.MULTILINE)valm=p.matcher("play\r\nscala")while(m.find()){println("find:"+m.group(0).length)}//输出find:5find:5输出的两个结果长度为5,因为play结尾有一个字符\r。4)Pattern.CASE_INSENSITIVE启用不区分大小写的匹配,相当于修饰符(?i)。valp=Pattern.compile("^S.*A$",Pattern.CASE_INSENSITIVE)valm=p.matcher("scala")println(m.matches())//输出true5)Pattern.LITERAL启用字面量(literal)模式解析,模式中的元字符和转义字符将被解析为普通字符。valp=Pattern.compile(".*",Pattern.LITERAL)valm=p.matcher("scala")println(m.matches())//输出false6)Pattern.COMMENTS正则表达式中允许有空格(whitespace)和注释(comments),空白字符会被忽略,以#开头的注释行也会被忽略,相当于修饰符(?x);valp=Pattern.compile(".*",Pattern.COMMENTS)valm=p.matcher("scala")println(m.matches())//输出true注意:有些编程语言(比如JavaScript)做不支持嵌入模式修饰符(embeddedmodemodifiers),那么可以使用另一种解决方案:[\s\S]*[\s]会匹配任何空白字符,而[\S]会匹配任何[\s]不能匹配的字符匹配。组合这两种形式[\s\S],得到一个包含所有字符(包括换行符)的字符组。
