正则表达式是一种强大而灵活的文本处理工具。使用正则表达式,我们能够以编程的方式,构造复杂的文本模式,并对输入的字符串进行搜索,一旦找到了匹配这些模式的部分,我们就可以随心所欲的对他们进行处理。正则表达式是一种简洁、动态的语言,除了语法是一个难点之外。
正则表达式提供了一种完全通用的方式,能够解决各种字符串处理相关的问题,包括:匹配、选择、编辑以及验证。
Java正则表达式通过java.util.regex包下的Pattern和Matcher类实现。
java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包。它包括两个类:Pattern和Matcher。
Pattern: Pattern是一个正则表达式经编译后的表现模式。
Matcher :Matcher对象是一个状态机器,它依据Pattern对象做为匹配模式对字符串展开匹配检查。
首先一个Pattern实例订制了一个所用语法与PERL(一种拥有各种语言功能的梦幻脚本语言)的类似的正则表达式经编译后的模式,也可以说是创建一个匹配模式,然后一个Matcher实例在这个给定的Pattern实例的模式控制下进行字符串的匹配工作。
Pattern类可以通过两个静态方法创建:compile(String regex)和compile(String regex,int flags),其中regex是正则表达式,flags为可选模式(如:Pattern.CASE_INSENSITIVE 忽略大小写)
实例:
Pattern pattern = Pattern.compile(".*/hello/.{1,}");
System.out.println(pattern.pattern());//返回此模式的正则表达式即.*/hello/.{1,}
应用正则表达式最简单的途径,是利用String类内建的功能:
System.out.println("-123456".matches("-?\\d+"));//返回true
System.out.println("+911".matches("-?\\d+"));//返回false
Pattern类还自带了一个非常有用的正则表达式工具:split()方法,其功能是“将字符串从正则表达式匹配的地方切开”,该方法有两种实现:
Pattern.split(CharSequence input) :
Pattern pattern = Pattern.compile(" ");
String str = "hello world hello world";
String [] array = pattern.split(str);
for(String s:array ) {
System.out.println(s);
}
//输出
-->hello
-->world
-->hello
-->world
Pattern.split(CharSequence input, int limit),其中limit为返回元素的个数:
实例:
Pattern pattern = Pattern.compile(" ");
String str = "hello world hello world";
String [] array = pattern.split(str,2);
for(String s:array ) {
System.out.println(s);
}
//输出
-->hello
-->world hello world
在细说一下Pattern.split(CharSequence input, int limit),当limit值大于所能返回的字符串的最多个数或者为负数,返回的字符串个数将不受限制,但结尾可能包含空串,而当limit=0时与Pattern.split(CharSequence input)等价,但结尾的空串会被丢弃。
我们可以使用Pattern类的split方法实现切割字符串,其实String类也自带split()方法,String类的split()方法也有两种实现:
String.split(String regex):
String str = "hello world hello world";
String [] arr = str.split(" ");
for(String st:arr ) {
System.out.println("--->"+st);
}
//输出
--->hello
--->world
--->hello
--->world
String.split(String regex, int limit):
String str = "hello world hello world";
String [] arr = str.split(" ",2);
for(String st:arr ) {
System.out.println("--->"+st);
}
//输出
--->hello
--->world hello world
除了split()切割方法之外,String类还自带了一个正则表达式的工具:替换
//替换所有的子串
System.out.println(str.replaceAll("o", "0"));
//替换第一个匹配的子串
System.out.println(str.replaceFirst("o", "0"));
//输出
-->hell0 w0rld hell0 w0rld
-->hell0 world hello world
Pattern类也自带一个静态匹配方法matches(String regex, CharSequence input),但只能进行全字符串匹配并且只能返回是否匹配上的boolean值
实例:
String s= "hello";
String str= "hello world hello world";
System.out.println(Pattern.matches("hello",s));//返回true
System.out.println(Pattern.matches("hello",str));//返回false
比起功能有限的String类,我们更愿意去构建一个功能强大的正则表达式对象,这里就需要引入Matcher类了,Pattern类中的matcher(CharSequence input)会返回一个Matcher对象。
Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持,要想得到更丰富的正则匹配操作,那就需要将Pattern与Matcher联合使用。
Matcher类常用的返回boolean值得匹配方法有:
Pattern pattern = Pattern.compile("hello");
String str = "hello world hello world";
String s = "hello";
Matcher matcher = pattern.matcher(str);
//尝试查找与该模式匹配的输入序列的下一个子序列
System.out.println("--->"+matcher.find());//--->true
//尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列
System.out.println("--->"+matcher.find(1));//--->true
System.out.println("--->"+matcher.find(15));//--->false
//尝试将从区域开头开始的输入序列与该模式匹配。
System.out.println("--->"+matcher.lookingAt());//--->true
//尝试将整个区域与模式匹配。
System.out.println("--->"+matcher.matches());//--->false
Matcher matcher1 = pattern.matcher(s);
System.out.println("--->"+matcher1.matches());//--->true
这里介绍下组的概念:组是用括号划分的正则表达式,可以根据组的编号来引用这个组。组号为0表示整个表达式,组号为1表示被第一对括号括起的组,依次类推,例如A(B©)D,组0是ABCD,组1是BC,组2是C。
Matcher类提供了start(),end(),group()分别用于返回字符串的起始索引,结束索引,以及匹配到到的字符串。
实例:
Pattern pattern = Pattern.compile("hello");
String str = "hello world hello world";
String s = "hello";
Matcher matcher = pattern.matcher(str);
matcher.find();
//返回以前匹配的初始索引
System.out.println("--->"+matcher.start());//--->0
//返回最后匹配字符之后的偏移量
System.out.println("--->"+matcher.end());//--->5
//返回由以前匹配操作所匹配的输入子序列
System.out.println("--->"+matcher.group());//--->hello
Matcher类提供了start(int gropu),end(int group),group(int i),groupCount()用于分组操作
实例:
Pattern pattern = Pattern.compile("(hello )(world)");
String str = "hello world hello world";
Matcher matcher = pattern.matcher(str);
matcher.find();
//返回此匹配器模式中的捕获组数
System.out.println("--->"+matcher.groupCount());//--->2
//返回在以前匹配操作期间由给定组捕获的输入子序列
System.out.println("--->"+matcher.group(1));//--->hello
//返回在以前匹配操作期间由给定组捕获的输入子序列
System.out.println("--->"+matcher.group(2));//--->world
//返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引
System.out.println("--->"+matcher.start(1));//--->0
//返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量
System.out.println("--->"+matcher.end(1));//--->6
//返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引
System.out.println("--->"+matcher.start(2));//--->6
//返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量
System.out.println("--->"+matcher.end(2));//--->11
Matcher类提供了两种用于重置当前匹配器的方法:reset()和reset(CharSequence input)
Pattern pattern = Pattern.compile("hello");
String str = "hello world hello world";
Matcher matcher = pattern.matcher(str);
matcher.find();
System.out.println("--->"+matcher.group());//--->hello
//重置匹配器
matcher.reset();
matcher.find();
System.out.println("--->"+matcher.group());//--->hello
//重置此具有新输入序列的匹配器
matcher.reset("world");
System.out.println(matcher.find());//返回false
上面我们看到的例子都是将正则表达式应用于静态字符串中,下面我们主要演示一下正则表达式在Java/IO中的应用:
读取本地文件实例:
Pattern pattern = Pattern.compile("hello");
Matcher matcher = null;
try {
StringBuilder sb = new StringBuilder();
BufferedReader in = new BufferedReader(new FileReader(new File("D:\\launchfile.txt").getAbsoluteFile()));
String line;
while( (line = in.readLine()) != null ){
matcher = pattern.matcher(line);
if(matcher.find()) {
sb.append(line);
sb.append("\n");
}
}
System.out.println(sb.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
扫描输入实例:
System.out.println("请输入您希望检索的数据:");
Scanner scanner = new Scanner(System.in);
String pattern ="hello";
while(scanner.hasNext(pattern)) {
scanner.next(pattern);
MatchResult match = scanner.match();
System.out.println(match.group());
}