欢迎来真孝善网,为您提供真孝善正能量书籍故事!

深入解析Java正则表达式(第四部分)

时间:11-09 名人轶事 提交错误

大家好,今天小编来为大家解答以下的问题,关于深入解析Java正则表达式(第四部分),这个很多人还不知道,现在让我们一起来看看吧!

有了上一章(正则表达式(三):python re模块)中python中re模块的铺垫,理解Java中正则表达式的使用就会简单很多。

Java 是一种广泛使用的编程语言。从jdk-1.4开始,标准库提供了java.util.regex包来支持正则表达式的使用。 Java中正则表达式的使用与Python中略有不同,主要是使用方式上。名字上的区别是显而易见的。 python中的两个核心对象是Pattern和Match,而在Java中是Pattern和Matcher

核心对象作用

1. re 模块

re模块中的Pattern对象作为匹配规则,代表文本模式。基于该模式,Pattern对象提供了对指定内容的多种处理操作,如:匹配、分割、子等; Match对象作为模式和指定内容的分组处理结果,提供了多种提取数据信息的方式,如:group、groups、span等,根据re模块中两个对象的使用特点,可以总结如下。

1、Pattern对象的主要功能是针对模式指定的内容提供多种处理方法,并且可以返回Match对象进一步提取处理结果或者直接返回处理结果;

2、Match对象是模式的分组处理对象,其主要功能是提取处理结果信息。

2. regex 包

Java标准库中的regex包提供的正则函数也依赖于两个核心对象,它们与re模块的核心对象名称相似,用法也非常相似。 regex包中的Pattern对象作为匹配规则、文本模式,并提供直接返回结果的函数,如匹配、分割等,这些函数直接返回模式处理后的结果。然而,涉及分组的操作都是由Matcher对象提供的。 Pattern 对象提供了match 函数来构造Matcher 对象。 Matcher对象提供分组处理和结果提取功能,如:find、group、start、end等。此外,Matcher对象还提供reset、replaceAll、lookingAt等功能。对比regex包和re模块对正则处理的使用,我们可以发现一个现象:

相同点:两个Pattern对象都提供了对正则模式中指定内容的直接处理,分组结果的提取也在Match|Matcher对象中完成。

不同点:re模块中Match对象提供的功能更侧重于分组结果的操作。 Pattern对象中提供了split、sub等直接返回结果的非分组相关函数;而regex包中的Pattern对象Matcher对象和Matcher对象都提供了非分组相关的函数,例如Pattern对象中的split函数和Matcher对象中的replaceAll函数。

下面列出 Pattern 对象中常用函数:

函数名称functioncompile(String regex) 返回根据指定正则表达式生成的Pattern模式对象compile(String regex, int flags)返回根据指定正则表达式和匹配flags生成的Pattern模式对象matches(String regex) , CharSequence input )) 判断正则表达式是否匹配指定内容并返回quote(String s) 将指定内容转换为文字值并返回matcher(CharSequence input) 返回由Pattern 对象和指定内容分割组成的Matcher 对象(CharSequence input) 拆分指定内容,返回拆分结果列表split(CharSequence input, int limit) 根据指定次数拆分指定内容,返回拆分结果列表

Pattern 的私有构造函数

。在开始介绍具体用途之前,先介绍一点。在Pattern 类中使用私有构造函数,并提供compile static函数来完成对象的构造。声明私有构造函数有很多场景。主要原因是在构造对象之前或之后执行一些额外的操作:

1.不需要实例化的实用类,例如java.lang.Math类

2.构造函数可能会失败并且不能返回null

3.控制实例化对象的数量,比如使用单例

4.静态函数可以更好地阐明实例化过程的含义,或者稍后将其他操作添加到静态函数中。

以Pattern类为例,之所以声明私有构造函数并使用静态函数来完成实例化,更倾向于采用第四种方法。 Pattern的构建需要一些复杂的操作。以new Pattern(.)的形式构造一个新的模式并没有多大意义,因为正则表达式是被编译成模式的,所以用静态函数compile来解释这个过程。

在类中将构造函数设置为私有有什么用?

Java Pattern 类没有公共构造函数,为什么?

编译、匹配和引用函数是Pattern 类提供的静态函数。由于Pattern类构造函数是私有的,因此提供了compile函数来生成Pattern对象; matches函数直接返回正则表达式是否匹配指定内容的结果。其内部实现过程仍然是先调用compile函数构造Pattern对象,然后调用match函数构造Matcher对象,最后使用Matcher对象的matches函数返回匹配结果; quote 函数返回正则表达式的文字内容。

例子:

导入java.util.regex.Pattern;

公开课T2

{

公共静态无效主(字符串[]参数)

{

字符串reg1="[\w]+";

字符串str1="1a2b3c";

模式模式=Pattern.compile(reg1);

System.out.println("reg1模式是"+pattern.toString());

System.out.println("str1 匹配是"+Pattern.matches(reg1,str1));

字符串reg2=Pattern.quote(reg1);

字符串str2=reg1;

System.out.println("str2匹配是"+Pattern.matches(reg2,str2));

}

}

运行结果:

reg1 模式是[w]+

str1 匹配为true

str2 matches is true 从上面的例子可以看出,quote函数返回的正则表达式的字面值就是它的普通含义字符,所以可以当做普通字符来匹配自己的字符。

matcher函数Pattern类中matcher函数的作用是构造一个Matcher对象并返回

例子:

导入java.util.regex.Pattern;

公开课T2

{

公共静态无效主(字符串[]参数)

{

字符串reg1="[\w]+";

模式pattern1=Pattern.compile(reg1);

模式pattern2=Pattern.compile(reg1);

System.out.println(模式1==模式2);

}

}

运行结果:

false 从例子中可以看出,相比Python中re模块的缓存实现,Java的regex包中的正则模式构造并没有实现缓存功能。这个实现可以在后续的编译静态函数中添加。

split 函数Pattern 类中的split 函数提供了分割指定内容的功能,并返回分割后的字符串数组。该函数包含一个可选的limit 参数,用于指定分割后数组元素数量的上限。默认值0 表示完全分割。

例子:

导入java.util.Arrays;

导入java.util.regex.Pattern;

公开课T2

{

公共静态无效主(字符串[]参数)

{

字符串reg="\d";

字符串str="1a2b3c";

模式pattern1=Pattern.compile(reg);

String[] arr1=pattern1.split(str);

String[] arr2=pattern1.split(str,2);

System.out.println("arr1="+Arrays.toString(arr1));

System.out.println("arr2="+Arrays.toString(arr2));

}

}

运行结果:

arr1=[, a, b, c]

arr2=[, a2b3c]

下面列出 Matcher 对象中常用函数:

函数名称matches() 判断正则表达式是否匹配指定内容并返回find() 从起点或上一个匹配位置之后开始查找是否有下一个匹配内容并返回find(int start )从指定位置或上一个匹配位置后重新开始查找是否有下一个匹配内容并返回group() 返回匹配内容group(int group) 返回指定序号组匹配内容group(String name) 返回指定名称组匹配的内容lookingAt() 重新判断正则模式是否匹配给定内容的起始部分并返回replaceAll(String replacement) 用指定内容替换所有匹配的内容并返回替换结果replaceFirst(String) replacement) 将第一个匹配内容替换为指定内容并返回替换后的结果start() 返回匹配内容的第一个下标start(int group) 返回指定序号组中匹配内容的第一个下标start(String name) 返回指定名称组中匹配内容的首下标end() 返回匹配内容结束下标end(int group) 返回指定序号组中匹配内容的尾下标end(String name) 返回匹配内容指定名称组匹配内容的尾部下标matches 函数Matcher 对象提供的matches 函数与Pattern 的静态函数matches 功能相同。判断正则表达式与内容是否完全匹配,并返回判断结果。

例子:

导入java.util.regex.Matcher;

导入java.util.regex.Pattern;

公开课T2

{

公共静态无效主(字符串[]参数)

{

字符串reg="[\w]+";

字符串str1="5b3ac";

字符串str2="5b3ac=";

模式模式=Pattern.compile(reg);

匹配器matcher1=pattern.matcher(str1);

匹配器matcher2=pattern.matcher(str2);

System.out.println("match1 matches="+matcher1.matches());

System.out.println("match2 matches="+matcher2.matches());

}

}

运行结果:

match1 匹配=true

match2 matches=falsefind 函数find 函数提供一个指定起始位置的参数。默认情况下,从起始位置或上一个匹配位置之后开始搜索下一个匹配内容。如果参数指定了起始位置,则从指定位置重新开始。开始寻找下一场比赛。

例子:

导入java.util.regex.Matcher;

导入java.util.regex.Pattern;

公开课T2

{

公共静态无效主(字符串[]参数)

{

字符串reg="\d";

字符串str="a1b2c3";

模式模式=Pattern.compile(reg);

匹配器matcher=pattern.matcher(str);

System.out.println("第一轮----");

System.out.println("第一次找到="+matcher.find());

System.out.println("第二个找到的="+matcher.find());

System.out.println("找到的第三个="+matcher.find());

System.out.println("找到第四个="+matcher.find());

System.out.println("n第二轮----");

System.out.println("第一次找到="+matcher.find(2)); //"b" 位置

System.out.println("第二个找到的="+matcher.find());

System.out.println("找到的第三个="+matcher.find());

System.out.println("找到第四个="+matcher.find());

}

}

运行结果:

第一轮----

第一次发现=true

第二个找到=true

第三个找到=true

第四个找到=假

第二轮----

第一次发现=true

第二个找到=true

第三个找到=假

第四个found=false 从例子中可以看出,find函数会按照匹配规则在给定的内容中从前往后进行匹配查询。当指定find函数的起始位置时,将从指定位置重新开始查询。

群函数群函数有三种形式:

1、无参数时返回整个正则表达式匹配内容。

2. 当指定组序号时,返回与指定序号的组匹配的内容。

3. 当指定组名称时,返回与指定名称的组匹配的内容。

例子:

导入java.util.regex.Matcher;

导入java.util.regex.Pattern;

公开课T2

{

公共静态无效主(字符串[]参数)

{

字符串reg="\d(\d)(?\d)";

字符串str="123abc456";

模式模式=Pattern.compile(reg);

匹配器matcher=pattern.matcher(str);

System.out.println("匹配器匹配="+matcher.find());

System.out.println("无参数="+matcher.group());

System.out.println("参数个数="+matcher.group(1));

System.out.println("名称参数="+matcher.group("id"));

}

}

运行结果:

匹配器匹配=true

无参数=123

数字参数=2

name参数=3lookingAt函数lookingAt函数有两个功能:

1、判断正则表达式是否匹配给定内容的开头

2、如果正则匹配到内容的开头部分,则从内容的开头部分再次查找匹配的内容,相当于执行find(0)函数

例子:

导入java.util.regex.Matcher;

导入java.util.regex.Pattern;

公开课T2

{

公共静态无效主(字符串[]参数)

{

字符串reg="\d";

模式模式=Pattern.compile(reg);

System.out.println("第一轮----");

字符串str="1a2b";

匹配器matcher=pattern.matcher(str);

System.out.println("第一次找到="+matcher.find()); //真的

System.out.println("第二个找到="+matcher.find());//true

System.out.println("找到的第三个="+matcher.find()); //错误的

System.out.println("lookingAt 找到="+matcher.lookingAt()); //reg 匹配str 的开头部分//true

System.out.println("第二个找到="+matcher.find());//true

System.out.println("第三个找到="+matcher.find());//false

System.out.println("n第二轮----");

字符串str2="a1b2";

匹配器matcher2=pattern.matcher(str2);

System.out.println("第一次找到="+matcher2.find());//true

System.out.println("第二个找到="+matcher2.find());//true

System.out.println("第三个找到="+matcher2.find());//false

System.out.println("lookingAt 找到="+matcher2.lookingAt()); //reg 与str 的开头部分不匹配//false

System.out.println("第二个找到="+matcher2.find());//false

System.out.println("第三个找到="+matcher2.find());//false

}

}

运行结果:

第一轮----

第一次发现=true

第二个找到=true

第三个找到=假

寻找发现=true

第二个找到=true

第三个找到=假

第二轮----

第一次发现=true

第二个找到=true

第三个找到=假

寻找发现=false

第二个找到=假

第三个found=false 从示例中可以看出,lookingAt 函数类似于String 对象的"startsWith" 函数。它确定常规模式是否与给定内容的起始部分匹配。另外,如果起始部分匹配成功,就相当于执行了一次。 find(0) 函数,将查询分组的起始位置设置在第一个匹配结果之后。

ReplaceAll 和replaceFirst 函数的使用非常相似。 ReplaceAll 替换内容中与常规模式匹配的所有部分,replaceFirst 替换内容中与常规模式匹配的第一部分。

例子:

导入java.util.regex.Matcher;

导入java.util.regex.Pattern;

公开课T2

{

公共静态无效主(字符串[]参数)

{

字符串reg="(\d)\d";

模式模式=Pattern.compile(reg);

字符串str="a12b34";

匹配器matcher=pattern.matcher(str);

System.out.println("replaceAll="+matcher.replaceAll("+"));

System.out.println("replaceFirst="+matcher.replaceFirst("+"));

}

}

运行结果:

全部替换=a+b+

ReplaceFirst=a+b34 此示例演示由Matcher 对象提供的与组无关的指定内容替换。

start和end函数都是与分组相关的函数。 start 函数返回指定组或整个正则表达式的第一个和最后一个匹配部分。

标,end 函数返回指定分组或整个正则表达式匹配部分的尾下标(左闭右开)。 示例: import java.util.regex.Matcher; import java.util.regex.Pattern; public class t2 { public static void main(String[] args) { String reg = "(?\d)(?\d)\d"; Pattern pattern = Pattern.compile(reg); String str = "a123b456"; Matcher matcher = pattern.matcher(str); if(matcher.find()) { System.out.println("regex matched = "+matcher.group()); System.out.println("number1 matched(using No) = "+matcher.group(1)); System.out.println("number2 matched(using name) = "+matcher.group("number2")); System.out.println("nregex start position = "+matcher.start()); System.out.println("number1 start(using No) position = "+matcher.start(1)); System.out.println("number2 start(using name) position = "+matcher.start("number2")); System.out.println("nregex end position = "+matcher.end()); System.out.println("number1 end(using No) position = "+matcher.end(1)); System.out.println("number2 end(using name) position = "+matcher.end("number2")); } } } 运行结果: regex matched = 123 number1 matched(using No) = 1 number2 matched(using name) = 2 regex start position = 1 number1 start(using No) position = 1 number2 start(using name) position = 2 regex end position = 4 number1 end(using No) position = 2 number2 end(using name) position = 3由示例可知,group、start、end 函数都提供有三种形式的函数,来获取分组匹配的内容信息。无参时面向的是整个正则表达式匹配结果;参数为分组序号时,面向的是指定序号分组匹配的部分;参数为分组名称时,面向的是指定名称分组匹配的部分。 针对 group、start、end 这些获取分组匹配信息的函数,在这里介绍可能出现的三种异常:IllegalStateException:获取分组匹配的内容相关信息之前,没有对正则模式执行匹配操作,或匹配操作失败了,则提示状态异常;IndexOutOfBoundsException:不存在指定分组序号匹配的结果时,提示序号越界异常;IllegalArgumentException:不存在指定分组名称匹配的结果时,提示参数异常。 示例: import java.util.regex.Matcher; import java.util.regex.Pattern; public class t2 { public static void main(String[] args) { String reg = "(?\d)(?\d)\d"; Pattern pattern = Pattern.compile(reg); String str = "a123b456"; Matcher matcher = pattern.matcher(str); System.out.println("IllegalStateException example = "); try { matcher.group(); } catch (IllegalStateException e) { System.out.println(e.toString()); } System.out.println("nIndexOutOfBoundsException example = "); try { matcher.find(); matcher.group(-1); } catch (IndexOutOfBoundsException e) { System.out.println(e.toString()); } System.out.println("nIllegalArgumentException example = "); try { matcher.group("number3"); //上一步已经执行过matcher.find() } catch (IllegalArgumentException e) { System.out.println(e.toString()); } } } 运行结果: IllegalStateException example = java.lang.IllegalStateException: No match found IndexOutOfBoundsException example = java.lang.IndexOutOfBoundsException: No group -1

好了,关于深入解析Java正则表达式(第四部分)和的问题到这里结束啦,希望可以解决您的问题哈!

用户评论

此生一诺

终于到了 Java 正则表达式的章节了!期待学习强大的匹配功能。

    有16位网友表示赞同!

执拗旧人

我的代码经常需要处理字符串,正则表达式太好用了!

    有17位网友表示赞同!

别留遗憾

看这个标题应该会学到很多实用的技巧吧?

    有20位网友表示赞同!

闷骚闷出味道了

我对 Java 的正则表达式不太了解,这篇文章可以让我补课学习吗?

    有8位网友表示赞同!

你身上有刺,别扎我

之前只用过 Python 的正则表达式,Java 的语法会不会不一样?

    有16位网友表示赞同!

┲﹊怅惘。

这篇教程讲得一定会很详细,我等着看我的 Java 代码匹配字符串能力提升!

    有18位网友表示赞同!

莫阑珊

学习了 Java 的正则表达式之后,感觉编程都简单了很多。

    有17位网友表示赞同!

|赤;焰﹏゛

在网上找了很多 Java 正则表达式的资料,这个标题看起来很有可靠性。

    有9位网友表示赞同!

拽年很骚

我现在就有一个问题需要用正则表达式来解决,希望这篇文章能给我启发!

    有6位网友表示赞同!

怅惘

Java 的开发环境太强大,再加上强大的正则表达式支持,什么难题都无法难倒我!

    有6位网友表示赞同!

青袂婉约

我已经掌握了一些基础的正则表达式知识,想进一步学习 Java 的更高级别用法。

    有11位网友表示赞同!

忘故

正则表达式是程序员必备的技能,Java 正则表达式尤为强大!

    有18位网友表示赞同!

屌国女农

我很喜欢看这类技术文章,这篇文章可以让我学到很多新的知识。

    有9位网友表示赞同!

伪心

这篇教程应该涵盖了 Java 正则表达式的常用用法吧?

    有18位网友表示赞同!

别悲哀

看完这篇文章后我可以独立完成更多的正则表达式操作了吗?

    有20位网友表示赞同!

你很爱吃凉皮

我一直在寻找学习 Java 正则表达式的有效资料,这个标题看起来很不错!

    有16位网友表示赞同!

最怕挣扎

如果能提供一些案例示例,效果一定会更好。

    有11位网友表示赞同!

眷恋

期待看到Java 正则表达式强大的应用场景!

    有11位网友表示赞同!

一样剩余

学习 Java 的正则表达式,可以让我编写更高效的代码!

    有6位网友表示赞同!

顶个蘑菇闯天下i

这个标题太吸引人了,我已经迫不及待想学习了!

    有9位网友表示赞同!

【深入解析Java正则表达式(第四部分)】相关文章:

1.蛤蟆讨媳妇【哈尼族民间故事】

2.米颠拜石

3.王羲之临池学书

4.清代敢于创新的“浓墨宰相”——刘墉

5.“巧取豪夺”的由来--米芾逸事

6.荒唐洁癖 惜砚如身(米芾逸事)

7.拜石为兄--米芾逸事

8.郑板桥轶事十则

9.王献之被公主抢亲后的悲惨人生

10.史上真实张三丰:在棺材中竟神奇复活