李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
正则表达式--组(Groups)
Leefs
2019-12-26 AM
2603℃
0条
# 正则表达式--组(Groups) ### 前言 本篇将讲述正则表达式中组(Groups)的概念和用法,希望可以给大家带来一点帮助。 ### 概念 组(Groups):是用括号划分的正则表达式,可以根据组的编号来引用某个组。 组号为0表示整个表达式,组号1表示被第一对括号括起来的组,依次类推。因此,在下面这个表达式, ```java A(B(C))D ``` 中有三个组:组0是ABCD,组1是BC, 组2是C。 ### 方法参数 Matcher对象提供了一系列方法,用以获取与组相关的信息: `public int groupCount():`返回该匹配器的模式中的分组数目,第0组不包括在内。 `public String group():`返回前一次匹配操作(例如find())的第0组(整个匹配)。 `public String group(int i):`返回在前一次匹配操作期间指定的组号,如果匹配成功,但是指定的组没有匹配输入字符串的任何部分,则将会返回null。 `public int start(int group):`返回在前一次匹配操作中寻找到的组的起始索引。 `public int end(int group):`返回在前一次匹配操作中寻找到的组的最后一个字符索引加一的值。 **示例** ```java public class Groups { static public final String POEM = "Twas brillig, and the slithy toves\n" + "Did gyre and gimble in the wabe.\n" + "All mimsy were the borogoves,\n" + "And the mome raths outgrabe.\n\n" + "Beware the Jabberwock, my son,\n" + "The jaws that bite, the claws that catch.\n" + "Beware the Jubjub bird, and shun\n" + "The frumious Bandersnatch."; public static void main(String[] args) { // ?m 启用多行模式 Matcher m = Pattern.compile("(?m)(\\S+)\\s+((\\S+)\\s+(\\S+))$").matcher(POEM); while (m.find()) { for (int j = 0; j <= m.groupCount(); j++){ printnb("[" + m.group(j) + "]"); } System.out.println(); } } } ``` > 运行结果 ```java [the slithy toves][the][slithy toves][slithy][toves] [in the wabe.][in][the wabe.][the][wabe.] [were the borogoves,][were][the borogoves,][the][borogoves,] [mome raths outgrabe.][mome][raths outgrabe.][raths][outgrabe.] [Jabberwock, my son,][Jabberwock,][my son,][my][son,] [claws that catch.][claws][that catch.][that][catch.] [bird, and shun][bird,][and shun][and][shun] [The frumious Bandersnatch.][The][frumious Bandersnatch.][frumious][Bandersnatch.] ``` 在正则表达式`(?m)(\\S+)\\s+((\\S+)\\s+(\\S+))$`中,目的是捕获每行的最后3个词,每行最后以`$`结束。不过,在正常情况下是将`$`与整个输入序列的末端相匹配。所以我们一定要显示地告知正则表达式注意输入序列中的换行符。这可以由序列开头的模式标记(?m)来完成。 如果本示例从这里结束了,可能大家心里还有许多疑问。 **问题1:为什么是捕获每行的最后3个词?** **?m**:表示所在位置右侧的表达式开启指定的多行匹配。更改`^`和`$的含义,以使它们分别与任何行的开头和结尾匹配。 **\s:**空白符(空格、tab、换行、换页和回车) **\S:**非空白符(`[^\s]`) 相信看过上方的说明就会更加清晰的理解了。通过?m开启多模式匹配,`$`说明匹配每行的结尾,其中两个`\s` 说明匹配两个空白符,也就是3个词。 **问题2:为什么每行的输出结果都是4个参数?** 首先我们在看一下组的概念,组是用括号划分的正则表达式,每一个括号中的内容就是一个字符串,也就是说,出现了多少对括号,就有多少组。并且组的编号是从1开始计算的。 解释到这一步我相信答案已经很清晰了,在下面就是小学生的找圈问题了,我就不再罗嗦了。 ### start()和end() 在**匹配结果成功之后**,start()返回先前匹配的起始位置的索引,而end()返回所匹配的最后字符的索引加一的值。在匹配操作失败之后(或先于一个正在进行的匹配操作去尝试)调用start()或end()将会产生`IllegalSta teException`。下面的示例还同时展示了matches()和`lookingAt()`的用法: ```java public class StartEnd { public static String input = "As long as there is injustice, whenever a\n" + "Targathian baby cries out, wherever a distress\n" + "signal sounds among the stars ... We'll be there.\n" + "This fine ship, and this fine crew ...\n" + "Never give up! Never surrender!"; private static class Display{ private boolean regexPrinted = false; private String regex; Display(String regex){ this.regex = regex; } void display(String message){ if(!regexPrinted){ System.out.println(regex); regexPrinted = true; } System.out.println(message); } } static void examine(String s, String regex){ Display d = new Display(regex); Pattern p = Pattern.compile(regex); Matcher m = p.matcher(s); while(m.find()){ d.display("find() '" + m.group() + "' start = " + m.start() + " end = " + m.end()); } if(m.lookingAt()){ d.display("lookingAt() start = " + m.start() + " end = " + m.end()); } if(m.matches()){ d.display("matches() start = " + m.start() + " end = " + m.end()); } } public static void main(String[] args){ for(String in : input.split("\n")){ System.out.println("input : " + in); for(String regex : new String[]{"\\w*ere\\w*", "\\w*ever", "T\\w+", "Never.*?!"}){ examine(in, regex); } } } } ``` > 运行结果 ```java input : As long as there is injustice, whenever a \w*ere\w* find() 'there' start = 11 end = 16 \w*ever find() 'whenever' start = 31 end = 39 input : Targathian baby cries out, wherever a distress \w*ere\w* find() 'wherever' start = 27 end = 35 \w*ever find() 'wherever' start = 27 end = 35 T\w+ find() 'Targathian' start = 0 end = 10 lookingAt() start = 0 end = 10 input : signal sounds among the stars ... We'll be there. \w*ere\w* find() 'there' start = 43 end = 48 input : This fine ship, and this fine crew ... T\w+ find() 'This' start = 0 end = 4 lookingAt() start = 0 end = 4 input : Never give up! Never surrender! \w*ever find() 'Never' start = 0 end = 5 find() 'Never' start = 15 end = 20 lookingAt() start = 0 end = 5 Never.*?! find() 'Never give up!' start = 0 end = 14 find() 'Never surrender!' start = 15 end = 31 lookingAt() start = 0 end = 14 matches() start = 0 end = 31 Process finished with exit code 0 ``` > 方法说明 **find():**可以在输入的任意位置开始匹配正则表达式; **lookingAt():**只能在字符串的开头开始匹配,但不需要整个字符串匹配成功; **matches():**也是只能在字符串的开头开始匹配,且需要整个字符串匹配成功。
标签:
Java
,
Java编程思想
,
字符串
,
正则表达式
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/338.html
上一篇
【转载】正则表达式--基础部分讲解(一)
下一篇
正则表达式--Pattern标记
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
Spring
算法
Thymeleaf
MyBatisX
Map
MyBatis
人工智能
数学
Eclipse
并发编程
正则表达式
链表
Nacos
ClickHouse
Python
字符串
序列化和反序列化
Jenkins
Spark
Spark Streaming
Golang
JavaSE
容器深入研究
高并发
查找
Java阻塞队列
Elasticsearch
工具
JavaWEB项目搭建
Stream流
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭