Java语言中的正则表达式

正则表达式是什么?

正则表达式是一种强大而灵活的文本处理工具。初学正则表达式时,其语法是一个难点,但它确实是一种简洁、动态的语言。正则表达式提供了一种完全通用的方式,能够解决各种字符串处理相关的问题:匹配、选择、编辑以及验证。一般来说,正则表达式就是以某种方式来描述字符串。

日常例子

在文本中查找“halu126”,我们通常会在查找框中输入“halu126”,这就是一个最简单的正则表达式的例子,使用精确的匹配这样的字符串,如果我 们即想在文本中找到“halu126”,又想找到“Halu126”,却不想找到“aaaHalu126bbbb”中的“Halu126”,该怎么办?

在linux中我们想查想列出所有的Java源文件,通常会在终端中输入:ls -all *.java,其中“*”是叫做通配符,而正则表达式比通配符更牛,它能更精确的描述你的需求。

正则表达式的构造摘要

构造 匹配
  字符
X 字符X
\\\\ 反斜线字符
\t 制表符
\n 换行符
\r 回车符
  字符类
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
  预定义字符类
. 任何字符
\d 数字:[0-9]
\D 非数字:[^0-9]
\s 空白字符:[\t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
  边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
\B 非(单词边界)
  量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好n次
X{n,} X,至少n次
X{n,m} X,至少n次,但是不超过m次
  Logical运算符
XY X后跟Y
X|Y X或者Y
(X) X,作为捕获组

组和捕获

捕获组可以通过从左到右计算其开括号来编号。例如,在表达式中((A)(B(C)))中,存在四个这样的组

1 ((A)(B(C)))
2 (A)
3 (B(C))
4 (C)

Java语言中正则表达式的不同处

在其他语言中,“
\\”表示“我想在正则表达式中插入一个普通的(字面上的)反斜线,请不要给它任何特殊的意义。”在Java语言中,“\\”表示“我要插入一个正则表达
式的反斜线,所以其后的字符具有特殊的意思。”例如:“\\d”表示Java语言中正则表达式的一位数字。“\\\\”表示一个普通的反斜线。不过换行和
制表符之类的东西只需要使用单反斜线:“\n\t”。

量词的类型:

量词:描述了一个模式吸收(匹配)输入文本的方式,也叫做重复限定符。
贪婪型:量词总是贪婪的,除非有其他的选项被设定。贪婪表达式会为所有可能的模式发现尽可能多的匹配。
勉强型:用问号指定,这个量词匹配满足模式所需的最少字符数。因此也称作懒惰的、最少匹配的、非贪婪的、或不贪婪的。
占有型Java中独有的。其他语言没有。当正则表达式被应用于字符序列时,它会产生相当多的状态,以便在匹配失败时可以回溯。而“占有的”量词并不保存这些中间状态,因此他们可以防止回溯。他们常常用于防止正则表达式失控,因此可以使正则表达式执行起来更有效。

Greedy数量词 Reluctant数量词 Possessive数量词
X? X?? X?+
X* X*? X*+
X+ X+? X++
X{n} X{n}? X{n}+
X{n,} X{n,}? X{n,}+
X{n,m} X{n,m}? X{n,m}+

量词作用的表达式通常必须要使用圆括号括起来。

String类中使用正则表达式的方法

matches(String regex)
split(String regex)
split(String regex, int limit)
replaceFirst(String regex, String replacement)
repalceAll(String regex, String replacement)

Java语言中表示正则表达式的类

在Java语言中与正则表达式相关的类都放在java.util.regex包。

  • *Pattern类:*pattern对象是一个正则表达式的编译表示。Pattern类没有公共构造方法。要创建一个Pattern对象,你必须首先调用其公共静态编译方法,它返回一个Pattern对象。该方法接受一个正则表达式作为它的第一个参数。
  • *Matcher类:*Matcher对象是对输入字符串进行解释和匹配操作的引擎。与Pattern类一样,Matcher也没有公共构造方法。你需要调用Pattern对象的matcher方法来获得一个Matcher对象。
  • *PatternSyntaxException:*PatternSyntaxException是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建Matcher对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。

因此,典型的调用顺序是

1 Pattern pattern = Pattern.compile("a*b");
2 Matcher matcher= pattern("aaaaaaab");
3 matcher.XXX();

一个简单的代码如下:

 1 public class TestRegularExpression {
 2     public static void main(String[] args) {
 3         if(args.length < 2) {
 4             print("Usage:\njava TestRegularExpression " +
 5                     "characterSequence regularExpression+");
 6             System.exit(0);
 7         }
 8         print("Input: \"" + args[0] + "\"");
 9         for(String arg : args) {
10             print("Regular expression: \"" + arg + "\"");
11             Pattern p = Pattern.compile(arg);
12             Matcher m = p.matcher(args[0]);
13             while(m.find()) {
14                 print("Match \"" + m.group() + "\" at positions " +
15                         m.start() + "-" + (m.end() - 1));
16             }
17         }
18     }
19 }

Pattern和Matcher类中常用的方法

 1 //使用Pattern类的静态方法compile来编译正则表达式,它会根据正则表达式regex生成一个Pattern对象。
 2 Pattern pattern = Pattern.compile(String regex)
 3 //检查regex是否匹配整个CharSequence类型的input参数
 4 Pattern.matches(String regex, CharSequence input)
 5 //从匹配了regex的地方分割输入字符序列input
 6 pattern.split(CharSequence input)
 7 //同String.split()
 8 pattern.split(CharSequence input, int limit)
 9 //根据模板pattern生成input的匹配器matcher
10 Matcher matcher = pattern.matcher(CharSequence input);
11 //从字符序列的开始位置(0位字符)迭代的向前遍历字符序列,找到匹配模式的部分
12 matcher.find()
13 //从字符序列的第start位字符开始(以第start位字符作为搜索的起点)迭代的向前遍历字符序列,找到匹配模式的部分
14 matcher.find(int start)
15 //判断整个输入字符序列是否匹配正则表达式模式
16 matcher.matches()
17 //判断该字符序列(不必是整个字符序列)的开始部分是否能够匹配模式
18 matcher.lookingAt()
19 //该匹配器的模式中的分组数目
20 matcher.groupCount()
21 //返回前一次匹配操作(例如find())的第0组(即整个匹配)
22 matcher.group()
23 //返回在前一次操作期间指定的组号,如果没有指定的组,返回null
24 matcher.group(int group)
25 //
26 matcher.start()
27 //返回前一次匹配操作中寻找到的组的起始索引
28 matcher.start(int group)
29 matcher.end()
30 //返回前一次匹配操作中寻找到的组的最后一个字符索引加一的值
31 matcher.end(int group)
32 //将matcher对象重新设置到当前字符序列的起始位置
33 matcher.reset()
34 将现有的matcher对象应用到一个新的字符序列
35 matcher.reset(CharSequence input)

使用正则表达式时要注意的事儿

要匹配一种情况,我们可以写出多个可行的正则表达式,当然了,我们的目的并不是编写最难理解的正则表达式,而是尽量编写能够完成任务的、最简单以及最必要的正则表达式。

参考

时间: 2024-10-13 11:49:51

Java语言中的正则表达式的相关文章

Java语言中反射动态代理接口的解释与演示

Java语言中反射动态代理接口的解释与演示 Java在JDK1.3的时候引入了动态代理机制.可以运用在框架编程与平台编程时候捕获事件.审核数据.日志等功能实现,首先看一下设计模式的UML图解: 当你调用一个接口API时候,实际实现类继承该接口,调用时候经过proxy实现. 在Java中动态代理实现的两个关键接口类与class类分别如下: java.lang.reflect.Proxy java.lang.reflect.InvocationHandler 我们下面就通过InvocationHan

原码、反码、补码相关内容以及Java语言中是以哪一种码表示的

计算机中的数字是以二进制方式存储的,第一个二进制位为符号位,0代表正数,1代表负数 原码.反码.补码是计算机中存储数字使用的编码 1.原码.反码.补码的概念 原码:符号位加上这个数绝对值 例如正整数1的8位二进制原码为 00000001      负整数-1的8为二进制原码为 10000001 反码:正数的反码就是其本身,负数的反码就是在原码的基础上除符号位外所有的位取反 例如正整数1的8位二进制原码为 00000001 则其反码还为 00000001  负整数-1的8为二进制原码为 10000

Java语言中学习数组、运算符、流程控制的一些理解

一.数组 1.数组的概念及作用 数组是相同数据类型的元素的集合:   数组本身是引用数据类型,即对象.但是数组可以存储基本数据类型,也可以存储引用数据类型. 例如: int [] a = new int [] {1,2,3,4,5,6,}; String [] s = new String [] {"小兔","小小兔","小小小兔",} : Employee [] e = Employee [10];(Employee是自定义类). 2.数组的声

在Java语言中调用存储过程、存储函数、包头、包体

需要拷贝连接Oracle的jar包,路径如下图所示: 连接Oracle数据库的代码: package demo.utils; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class JDBCUtils { private static Stri

Java语言中的定义变量、构造函数

day02 Java语言中的定义类.变量.方法.构造函数 一.概述: 在Java语言中,变量的定义和使用时非常常见和重要的:同时对后续的操作变量奠定基础,在这里定义和使用变量就要使用到我们前一节说到的数据类型了,它们两个就是绑定在一起使用的.我们回顾一下前一节学的数据类型. 学完变量以后就要学会使用变量去定义一些东西,去构造我们需要的一些方法来满足学习的需要.从而引申出了构造这一个词汇.构造就是创造的含义,通过创造一些东西来满足.下面就一一的来看一下. 二.定义"类"(class):

Java语言中的----运算符

day05 Java语言中的----运算符 一.运算符概述: 运算符的使用在每一门开发语言中都会使用到,在不同的语言中也会有不同的使用规则.通过运算符我们可以联想到MySQL数据库中的运算符,这些都是差不多的,可能有些在使用上是不一样的.下面就来看看Java中的运算符. 二.运算符: 1.算术运算符: 主要包含:加.减.乘.除.取余(%).自加(++).自减(--) 2.赋值运算符: 就是等号(=) 3.位运算符: 主要包含:&.|.~.^.<<.>>.>>&g

Java语言中使用OpenMP

从去年年中,开始学习Java,主要是维护公司用Java编写的服务器软件.目前,该服务器软件遇到一个问题,在下载大文件时,如果同时下载的用户很多, 服务器软件工作会出现异常,有的用户无法下载.服务器硬件基本上都是多核处理器,所以,如果能在Java语言中使用并行编程技术,使用OpenMP,可能 会提高服务器软件的性能. 今天,测试了一下,Java语言中也可以使用OpenMP.以下是详细测试过程: 1. 下载jomp1.0b.jar https://www2.epcc.ed.ac.uk/computi

Java语言中的----条件循环

day06 Java语言中的条件循环 一.条件循环概述: 条件循环对于我们来说一点也不陌生,在程序中使用循环语句是很普片的事儿,所以说你一定得学会循环语句. 二.条件循环 条件循环主要包括两个循环语句,分别是if...else和switch...case语句. 1.if循环结构         if (){                  }else{                  } 2.switch...case循环结构         switch () {     case 1:

Java语言中的---访问说明符

day03  Java语言中的-----访问说明符 一.访问说明符的概述: 访问说明符其实就是设置一个访问权限,只有设置好这个访问权限以后才能更好的封装我们的一些变量或方法.所以学好这个说明符对我们后续学习Java的封装功能很有帮助. 二.访问说明符:  1.访问说明符有哪些? 在Java语言中,访问说明符就可以实现对类成员的一个封装,从而就按包含4种说明符,public.private.default.protected.下面就一一的介绍一下. 1.1.public :公开的.可以被任何类访问