JAVA 正则表达式入门

简介: java中的正则表达式遵循了像Python,unix中的一些工具相同的语法,使得正则表达式可以通用。<br> 正则表达式是强大而灵活的文本处理工具。他们可以让我们以变成编程的方式找到文本中符合某种模式的内容,<br> 然后我们能够对这些内容进行处理,例如:匹配、验证、选择等等。<br><br><h3>常用正则表达式模式</h3> <p>在jdk文档的Pattern类中有更加详细的模式
java中的正则表达式遵循了像Python,unix中的一些工具相同的语法,使得正则表达式可以通用。
正则表达式是强大而灵活的文本处理工具。他们可以让我们以变成编程的方式找到文本中符合某种模式的内容,
然后我们能够对这些内容进行处理,例如:匹配、验证、选择等等。

常用正则表达式模式

在jdk文档的Pattern类中有更加详细的模式说明

构造                   匹配
字符
x                                         字符x
/uhhhh                            用16进制0xhhhh表示的unicode字符
/t                                    制表符
/n                                    换行符
/r                                    回车
/f                                    换页
字符类
[abc]                                a|b|c
[^abc]                            除了a,b,c之外的字符
[a-z]                                范围
[ab[cd]]                        并集
[a-z&&[abc]]                交集
预定义
.                                        任意字符
/s                                    空白字符(/t,/n,/r,/f)
/S                                    非空白字符
/d                                    数字[0-9]
/w                                    单词字符[a-zA-Z_0-9]
逻辑运算
XY                                    X后面跟Y
X|Y                                    X或Y
(X)                                    捕获组,能够用表达式/i引用第i个组
边界匹配
^                                        一行的开始
$                                        一行的结束
/b                                    词界
/B                                    非词界
/G                                    上一级的结尾
量词
x?                                    0或1
x*                                    0或多
x+                                    1或多
x{n}                                恰好n次
x{n,}                                恰好n次
x{n,m}                            >=n但是<m

上面就算是一些基本的语法了,下面我们来看一下在java中应该如何进行使用
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
System.out.println(m.matches());
其中Pattern为正则表达式的编译表现形式,它需要接收实现了CharSequence接口的类,比如String,StringBuffer等,然后编译成正则表达式。
然后使用了p.matcher(String s)方法得到匹配器Matcher.通过匹配器提供的方法我们能够能够找到s中与模式相匹配的这个子字符串以及其所在的位置等等。
p.matcher方法表示的是将整个字符串与模式进行匹配,能够匹配则返回true。匹配
下面就来看看具体我们能够进行哪些操作。
这之前还有一点要说的是,java语言中的表达式与其他语言在处理反斜杠的方式有些不同。
其他语言中"//"意味着我想在一个正则表达式中插入一个无格式的字面意义上的反斜杠。

而在java中,"//"意味着我正在插入一个正则表达式反斜杠,那么其后面的字符具有特殊的意义。例如我们想表达一个或者多个字符我们的正则表达式需要是"//w+"的这种形式。,如果我们想插入一个字面意义的反斜杠则是"////"。但是像制表符这样的字符只需要用到一个反斜杠:"/n/t"。

public class FindDemo {
	public static void main(String[] args) {
		Matcher m = Pattern.compile("//w+").matcher("Evening is full of the linnet's wings");
		while(m.find()){
			System.out.println(m.group() + "");
		}
		int i = 0;
		while(m.find(i)){
			System.out.print(m.group() + " ");
			i++ ;
		}
	}
}

find()尝试查找与该模式匹配的输入序列的下一个子序列。从序列的开头开始,如果成功调用了一次这个方法,下一次调用之后会从匹配
find(int start)重置此匹配器,然后从输入序列中尝试查找匹配该模式的,从指定索引开始的下一个子序列。
group() 相当于group(0)
group(i) 返回上一次匹配捕获的子序列。0表示的就是整个子序列。

分组

A(B(C))D        这个表达式表示了三个组0 ABCD,1 BC, 2 C
可以使用groupCount()当前匹配子序列中的分组的数目。第0组不包括在内。
start(int group)返回在前一次匹配中找到的该组的起始下标。end(int group)返回在前一次匹配操作中族的最后一个字符的下标加1
看例子:

public class GroupDemo {
	static public final String poem = 
		"Twas bringling,and the slithy toves/n"
		+ "Did gyre and gimble in the wabe./n"
		+ "All mimsy were the borogoves,/n"
		+ "And the mome raths outgarab./n/n";
	public static void main(String[] args) {
		Matcher m = Pattern.compile("(?m)(//S+)//s+((//S+)//s+(//S+))$").matcher(poem);
		while(m.find()){
			for (int i = 0; i < m.groupCount(); i++) {
				System.out.println("[" + m.start(i) +  m.group(i) + m.end(i) + "]");
			}
		}
	}
}

正则表达式为:(?m)(//S+)//s+((//S+)//s+(//S+))$
我们先来看一下它表达的意思。?m叫做模式标记,暂时记住它的意思是按照每一行来算末尾。
然后去掉分组的括号来看它表达的意思是:若干非空白符,若干空白符,若干非空白符,若干空白符,若干非空白符,结尾。显然这是要获取每一行的最后三个单词。

按照第一行为例,会匹配到the slithy toves。那么0组就是the slithy toves。1组就是the。。。

m.start(i)得到组的开始的下标 m.start()方法相当于调用了m.start(0);

模式标记

public class MatcherFlag {
	public static void main(String[] args) {
		Pattern p = Pattern.compile("^java", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
		// Pattern p = Pattern.compile("(?m)(?i)^java");
		Matcher m = p.matcher("java has regex/nJava has regex/nJAva has");
		while(m.find()){
			System.out.println(m.group());
		}
	}
}
上面演示了两种设置模式标记的方式。
常用的有Pattern.CASE_INSENSITIVE        (?i)大小写不敏感
Pattern.COMMENTS                                        (?x)空格将被忽略掉。并且以#开头的注释也会被忽略
Patten.MULTILINE                                        (?m)在多行模式下,表达式'^'和'$'分别匹配一行的开始和结束。

使用正则表达式的操作:

public class Split {
	public static void main(String[] args) {
		String s = "123.abc.你好";
		String[] ss1 = Pattern.compile(".").split(s);
		String[] ss2 = Pattern.compile("//.").split(s);
		String[] ss3 = s.split("//.");
		String[] ss4 = Pattern.compile("//.").split(s,2);
		System.out.println("==================");
		for (int i = 0; i < ss1.length; i++) {
			System.out.println(ss1[i]);
		}
		System.out.println("==================");
		for (int i = 0; i < ss2.length; i++) {
			System.out.println(ss2[i]);
		}
		System.out.println("==================");
		for (int i = 0; i < ss3.length; i++) {
			System.out.println(ss3[i]);
		}
		System.out.println("==================");
		for (int i = 0; i < ss4.length; i++) {
			System.out.println(ss4[i]);
		}
	}
}
实际上s.split()方法在源代码中就是调用了Pattern.compile("//.").split(s,0)的方法。
它表示以正则表达式为分界点,对实现了CharSequence接口的对象进行分割。split(s, limit)中的limit表示分为几项。分割之后剩下的所有内容为最后一项。
要注意使用特殊符号作为分割符的时候需要使用其正则表达式的字面意义。

替换操作

public class TheReplacement {
	public static void main(String[] args) {
		String s = " you are   a pretty  girl /n" + "  i love   you";
		String tempS = "";
		tempS = s.replaceAll(" {2,}", " ");
		// 相当于tempS = Pattern.compile(" {2,}").matcher(s).replaceAll(" ");
		System.out.println(tempS);
		tempS = s.replaceAll(" {2,}", " ").replaceFirst("[aeiou]", "(VOWEL1)");
		System.out.println(tempS);
		
		Matcher m = Pattern.compile("[aeiou]").matcher(s);
		StringBuffer sb = new StringBuffer();
		while(m.find()){
			m.appendReplacement(sb, m.group().toUpperCase());
			System.out.println("===" + sb);
		}
		
		m.appendTail(sb);
		System.out.println("---" + sb);
		
		sb.setLength(0);
		m = Pattern.compile("(//S+) (//S+)").matcher(s);
		while(m.find()){
			m.appendReplacement(sb, "$1===");
			System.out.println(sb);
		}
		
	}
}
主要有如下的可用的方法:
另外还有个方法需要说一下m.reset()方法将会把其置为开始的状态。
replaceFirst("regex", "replace")替换在输入序列中查找到的第一个子序列。
replaceAll(...,...)替换在输入序列中查找到的所有子序列。
m.appendReplacement(StringBuffer , "replace");
这个语句在relace中有$符号和没有$符号的表现是不相同的。
没有的时候表示把输入序列中查找到的匹配的子序列使用replace字符替换到,并且把start()位置和end()位置之间的字符串压入sb。
有$符号的意义在于,把输入序列中匹配的序列中的对应的组的后面加入replace符号,然后压入sb。
m.appendTail(sb)表示把end()位置之后的所有的字符串都压入sb。
在使用正则表达式的时候一定要注意他们时刻的指针指向情况,和注意他们是遍历执行的。

相关文章
|
1月前
|
自然语言处理 Java
Java中的字符集编码入门-增补字符(转载)
本文探讨Java对Unicode的支持及其发展历程。文章详细解析了Unicode字符集的结构,包括基本多语言面(BMP)和增补字符的表示方法,以及UTF-16编码中surrogate pair的使用。同时介绍了代码点和代码单元的概念,并解释了UTF-8的编码规则及其兼容性。
109 60
|
2月前
|
监控 架构师 Java
Java虚拟机调优的艺术:从入门到精通####
本文作为一篇深入浅出的技术指南,旨在为Java开发者揭示JVM调优的神秘面纱,通过剖析其背后的原理、分享实战经验与最佳实践,引领读者踏上从调优新手到高手的进阶之路。不同于传统的摘要概述,本文将以一场虚拟的对话形式,模拟一位经验丰富的架构师向初学者传授JVM调优的心法,激发学习兴趣,同时概括性地介绍文章将探讨的核心议题——性能监控、垃圾回收优化、内存管理及常见问题解决策略。 ####
|
2月前
|
监控 Java Python
Java 中的正则表达式
正则表达式是Java中强大的文本处理工具,支持灵活的匹配、搜索、替换和验证功能。本文介绍了正则表达式的语法基础及其在Java中的应用,包括字符串匹配、替换、分割及实际场景中的邮箱验证和电话号码提取等示例。通过这些技术,可以显著提高文本处理的效率和准确性。
247 8
|
2月前
|
安全 Java API
Java中的Lambda表达式:简化代码的现代魔法
在Java 8的发布中,Lambda表达式的引入无疑是一场编程范式的革命。它不仅让代码变得更加简洁,还使得函数式编程在Java中成为可能。本文将深入探讨Lambda表达式如何改变我们编写和维护Java代码的方式,以及它是如何提升我们编码效率的。
|
2月前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
102 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
2月前
|
Java API 开发者
Java中的Lambda表达式与Stream API的协同作用
在本文中,我们将探讨Java 8引入的Lambda表达式和Stream API如何改变我们处理集合和数组的方式。Lambda表达式提供了一种简洁的方法来表达代码块,而Stream API则允许我们对数据流进行高级操作,如过滤、映射和归约。通过结合使用这两种技术,我们可以以声明式的方式编写更简洁、更易于理解和维护的代码。本文将介绍Lambda表达式和Stream API的基本概念,并通过示例展示它们在实际项目中的应用。
|
3月前
|
安全 Java API
Java中的Lambda表达式与Stream API的高效结合####
探索Java编程中Lambda表达式与Stream API如何携手并进,提升数据处理效率,实现代码简洁性与功能性的双重飞跃。 ####
44 0
|
3月前
|
Java API 开发者
Java中的Lambda表达式:简洁代码的利器####
本文探讨了Java中Lambda表达式的概念、用途及其在简化代码和提高开发效率方面的显著作用。通过具体实例,展示了Lambda表达式如何在Java 8及更高版本中替代传统的匿名内部类,使代码更加简洁易读。文章还简要介绍了Lambda表达式的语法和常见用法,帮助开发者更好地理解和应用这一强大的工具。 ####
|
3月前
|
并行计算 Java 编译器
深入理解Java中的Lambda表达式
在Java 8中引入的Lambda表达式,不仅简化了代码编写,还提升了代码可读性。本文将带你探索Lambda表达式背后的逻辑与原理,通过实例展示如何高效利用这一特性优化你的程序。
|
3月前
|
Java 程序员 数据库连接
Java中的异常处理:从入门到精通
在Java编程的海洋中,异常处理是一艘不可或缺的救生艇。它不仅保护你的代码免受错误数据的侵袭,还能确保用户体验的平稳航行。本文将带你领略异常处理的风浪,让你学会如何在Java中捕捉、处理和预防异常,从而成为一名真正的Java航海家。

热门文章

最新文章