李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
正则表达式--组(Groups)
Leefs
2019-12-26 AM
3060℃
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://www.lilinchao.com/archives/338.html
上一篇
【转载】正则表达式--基础部分讲解(一)
下一篇
正则表达式--Pattern标记
取消回复
评论啦~
提交评论
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
48
NLP
8
标签云
微服务
序列化和反序列化
Shiro
Kafka
高并发
JVM
JavaScript
Netty
栈
Elastisearch
Kibana
Spark Streaming
Nacos
前端
Livy
GET和POST
MySQL
DataWarehouse
Git
Beego
哈希表
Redis
链表
二叉树
nginx
VUE
ClickHouse
Flink
算法
人工智能
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞