Java多可立,java正则 正则表达式 多行匹配 | 个人空间|张先立|宝宝

本文介绍了Java中如何使用Pattern.DOTALL和CASE_INSENSITIVE标志进行多行匹配,包括如何避免因不当使用.|导致的效率问题。重点讲解了多选结构|的应用技巧,以及如何优化选择结构以提高匹配速度。
摘要由CSDN通过智能技术生成

1:多行匹配

在默认的情况下 . 是不能匹配行结束符的(行结束符有 6 个,具体的可以看看 Pattern 的 API DOC)

同样,可以像不匹配大小写匹配那样使用编译参数:Pattern.DOTALL

如果还得区分大小写的话,还得加上上面说到的 Pattern.CASE_INSENSITIVE 这个,举个例子:

Java codeimport java.util.regex.Matcher;

import java.util.regex.Pattern;

public class Test {

public static void main(String[] args) {

String str =

“ 

                 \n” +

“   

               \n” +

“       Hello World!    \n” +

“   

              \n” +

“ 

                \n” +

”;

String regex = “

(.+?)”;

Pattern pattern = Pattern.compile(regex);

Matcher matcher = pattern.matcher(str);

while(matcher.find()) {

System.out.println(matcher.group(1).trim());

}

}

}

上面这个是不能从 str 抽取出东西的,因为 td 的后面带有换行符,我们只要更改一下:

Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);

这样就行了,如果 td 还得不区分大小写的话,再改成:

Java codePattern pattern = Pattern.compile(regex, Pattern.DOTALL | Pattern.CASE_INSENSITIVE);

这样的话,td 哪怕是大写的这个表达式都能把 td 之间的字符区抽取出来。

当然和 Pattern.CASE_INSENSITIVE 一样,Pattern.DOTALL 也有内嵌标志表达式,即 (?s)

s 的意思表示 single-line 就是忽略换行符什么的,只看成单行进行处理。

这个表达式使用内嵌 (?s) 的话可以改为:

Java codeString regex = “(?s)

(.+?)”;

如果还要不区分大小写的话,再加上 i 标志:

String regex = “(?s)(?i)

(.+?)”;

但这样显得很拖沓,可以把它们合并起来:

String regex = “(?is)

(.+?)”;    // 秩序无所谓

最后需要说明一下的是,我曾看到过由于不明白 DOTALL,为了让 . 匹配行结束符,直接把表达式写成:

Java codeString regex = “

((.|\\s)+?)”;

这样做是极其危险的,由于选择结构的匹配效率问题,这样做在比较长的字符串时会造成堆栈溢出,

使程序崩溃,如果使用 DOTALL 或者 (?s) 的话就不会出现这种情况。

4:2个单元的或操作

| 称为多选结构,用于匹配 | 之中的任何一个,拿你的例子来说明:

Java codeimport java.util.regex.Matcher;

import java.util.regex.Pattern;

public class Test {

public static void main(String[] args) {

String str =

                “1.gif%5C%E2%80%9D\n” +

                “1.gif%5C%E2%80%9D\n” +

                “1.gif%5C%E2%80%9D”;

        String regex = “”;

Pattern pattern = Pattern.compile(regex);

Matcher matcher = pattern.matcher(str);

while(matcher.find()) {

System.out.println(matcher.group());

}

}

}

注意到其中的 (?:ww|3) 在进行多选匹配时尽量找出多选中的规律,以减少多选的字符,

www 和 3w 在最后一个字符可以共用,前面的不一样。

(?: ) 的意思表示组成一组,如果没有 (?: ) 这样的话,表达式就变成了:

Java codeString regex = “”;

这样的语义完全变掉了,| 是在一组中进行选择,由于上面的那个表达式中没有组,就把整个表

达式作为了一组,使用 | 的话,就进行了整个表达式的多选结构了。这个表达式的意思是:

匹配 ,这样的结果并不是我们所要的。

我们仅仅需要在 ww 和 3 之间进行选择,这时只要把 ww 和 3 放在一组中进行多选择就可以了,

变成 (?:ww|3)。

还有,在多选结构中尽量把出现频率高的放在前面,这样可以加快匹配速度。

多选结构的效率在传统型的引擎中是效率低下的,如果是单个字符的选择,比如 a $ & 之中的一个,

那就不要使用 (?:a|$|&) 了,可以直接使用字符类 [a$&] 就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值