分类:
版权声明:本文为博主原创文章,未经博主允许不得转载。
正则表达式概念
- 所谓正则表达式就是处理字符串的特殊字符串
- 用途
- 字符串匹配(字符匹配)
- 字符串查找(是建立在匹配之上的查找)
- 字符串替换(是建立在查找的结果之后的替换)
- 例如
- IP地址是否正确
- 从网页中揪出Email地址
- 从网页揪出链接
- 类
- java.lang.String
- java.util.regex.Pattern
- java.util.regex.Matcher
- 要点
- //一个反斜线
- String str1 = "\";
- //正则表达式的一个反斜线使用两个反斜线,在java中表示就再需要两个反斜线转义
- System.out.println(str1.matches("\\"));
- //POSIX Style,这种写法不建议使用,如果要使用查API
- System.out.println("a".matches("\p{Lower}"));
- //空白行
- " ".matches("^[\s&&[^ ]]*\n$");
- //邮箱
- String regex1 = "[\w[.-]]+";
- String regex2 = "@";
- String regex3 = "[\w[.-]]+";
- String regex4 = "\.";
- String regex5 = "[\w]+";
- String regex = regex1+regex2+regex3+regex4+regex5;
- System.out.println("156112846@qq.com".matches(regex));
正则表达式的基本语法
- 普通字符(字母,数字,汉字,下划线)
- 一个普通字符在表达式中只匹配与之相同的一个字符
- 表达式k在字符串sky进行匹配时,将匹配成功
- , , ,f
- 表示回车符,换行符,制表符,换页符
- .
- 任意一个字符
- X?
- 表示X可以出现0次或者1次
- X+
- 表示X可以出现1次或者多次
- X*
- 表示X可以出现任意次
- X{n}
- 表示X可以出现n次
- X{m,n}
- 表示X可以最少出现m次,最多出现n次
- X{n,}
- 表示X最少出现n次
- [ ]
- 匹配中括号中任意一个字符
- [^ ]
- 匹配中括号中字符之外的任意一个字符
- d
- 表示0~9之间的任意一个数字字符,即[0-9]
- D
- 表示0~9之外的任意数字字符,即[^0-9]
- , , ,f
- 表示回车符,换行符,制表符,换页符
- s
- 表示空格,制表符,换页符等空白字符的任意一个
- S
- 表示空白字符以外的任意一个字符,即[^s]
- w
- 表示字母,数字,下划线中的任意一个字符,即[a-zA-Z_0-9]
- W
- 表示字母,数字,下划线以外的任意一个字符,即[^a-zA-Z_0-9]
- ^
- 该符号不匹配任何字符,字符串开始的位置,即^h必须以h开头
- $
- 该符号不匹配任何字符,字符串结束的位置,即r$必须以r结尾
- 该符号不匹配任何字符,表示单词的边界
- B
- 该符号不匹配任何字符,表示非单词的边界,即[^]
- |
- 用来连接两个表达式,表示或的关系
- X|Y 表示X或者Y中的任意字符
- ()
- 作为一个单元,一个分组
- (n表示一个数字)
- 有分组的情况下,表示对分组的引用
- 1表示对分组1的引用
- 转义字符,当一个符号自身有意义而又要表示这个字符的时候,就需要转义
- ^表示^,$表示$
- ?
- 如果在?,+,*,{n},{m,n},{n,}后面,表示次数按非贪婪模式进行匹配,
- 即按照匹配模式进行最小限度的匹配
扩展内容
贪婪 VS 非贪婪 VS 独占
- package com.itlwc;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- public class Test {
- public static void main(String[] args) throws Exception {
- String str = "aaaa5bbbb6";
- /*
- * 贪婪的
- * 一次吃进最多的10个字符,不匹配,再吐出来一个,匹配了,结束了
- */
- String regex1 = ".{3,10}[0-9]";
- Matcher m1 = Pattern.compile(regex1).matcher(str);
- if (m1.find())
- System.out.println(m1.start() + "-" + m1.end());
- else
- System.out.println("not match!");
- /*
- * 非贪婪的
- * 一次吃进最少的3个字符,然后看后面哪个是不是数字,
- * 再吞一个,然后再看后面哪个是不是数字,匹配了,结束了
- */
- regex1 = ".{3,10}?[0-9]";
- m1 = Pattern.compile(regex1).matcher(str);
- if (m1.find())
- System.out.println(m1.start() + "-" + m1.end());
- else
- System.out.println("not match!");
- /*
- * 独占的
- * 一次吃进最多的10个字符,不匹配,不吐出来,不匹配了,结束了
- */
- regex1 = ".{3,10}+[0-9]";
- m1 = Pattern.compile(regex1).matcher(str);
- if (m1.find())
- System.out.println(m1.start() + "-" + m1.end());
- else
- System.out.println("not match!");
- }
- }
- /*
- 打印结果:
- 0-10
- 0-5
- not match!
- */
非捕获组
- package com.itlwc;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- public class Test {
- public static void main(String[] args) throws Exception {
- System.out.println("--打印以a结尾的子串---");
- String str = "444a66b";
- String regex = ".{3}a";
- Matcher m = Pattern.compile(regex).matcher(str);
- while (m.find())
- System.out.println(m.group());
- System.out.println("--打印以a结尾的子串,但不捕获a--");
- // 非捕获组,这块的意思是不捕获a,算在这三个字符之中的
- regex = ".{3}(?=a)";
- m = Pattern.compile(regex).matcher(str);
- while (m.find())
- System.out.println(m.group());
- System.out.println("--这个例子和上面例子相似,但结果出乎意料--");
- // 非捕获组,不算在这三个字符之中的
- regex = "(?=a).{3}";
- m = Pattern.compile(regex).matcher(str);
- while (m.find())
- System.out.println(m.group());
- System.out.println("--打印前面不能是a的子串");
- regex = "(?!a).{3}";
- m = Pattern.compile(regex).matcher(str);
- while (m.find())
- System.out.println(m.group());
- System.out.println("--这个例子和上面例子相似,结果需要注意--");
- // 这个是先找444,后面是a不匹配再找44a,后面不是a,匹配
- regex = ".{3}(?!a)";
- m = Pattern.compile(regex).matcher(str);
- while (m.find())
- System.out.println(m.group());
- regex = ".{3}(?<!a)";
- }
- }
- /*
- 打印结果:
- --打印以a结尾的子串---
- 444a
- --打印以a结尾的子串,但不捕获a--
- 444
- --这个例子和上面例子相似,但结果出乎意料--
- a66
- --打印前面不能是a的子串
- 444
- 66b
- --这个例子和上面例子相似,结果需要注意--
- 44a
- 66b
- */
向前引用
- package com.itlwc;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- public class Test {
- public static void main(String[] args) throws Exception {
- // 第一组找到12,1的意思是后面的必须和第一组一样
- Matcher m1 = Pattern.compile("(\d\d)\1").matcher("1212");
- System.out.println(m1.matches());
- //1212不匹配,121不匹配,122匹配
- Matcher m2 = Pattern.compile("(\d(\d))\2").matcher("1212");
- System.out.println(m2.matches());
- }
- }
- /*
- 打印结果:
- true
- false
- */
flags简写
- package com.itlwc;
- import java.util.regex.Pattern;
- public class Test {
- public static void main(String[] args) throws Exception {
- Pattern.compile("java", Pattern.CASE_INSENSITIVE);
- //上下代码是等价的
- System.out.println("JAVA".matches("(?i)(java)"));
- System.out.println("java".matches("(?i)(java)"));
- }
- }
- /*
- 打印结果:
- true
- true
- */
String中正则表达式的使用
- package com.itlwc;
- public class Test {
- public static void main(String[] args) throws Exception {
- String str = "abc:0000:defg";
- System.out.println(str.replace("0000","8765"));
- // 替换所有匹配正则表达式的
- System.out.println(str.replaceAll("\d", "0"));
- // 只替换第一个匹配正则表达式的
- System.out.println(str.replaceFirst("\d", "1"));
- // str是否匹配给定正则表达式
- System.out.println(str.matches(".{13}"));
- //拆分
- for(String s : str.split(":")){
- System.out.print(s+" ");
- }
- System.out.println();
- //拆分几段
- for(String s : str.split(":",2)){
- System.out.print(s+" ");
- }
- }
- }
- /*
- 打印结果:
- abc:8765:defg
- abc:0000:defg
- abc:1000:defg
- true
- abc 0000 defg
- abc 0000:defg
- */
Pattern概述
- java.util.regex.Pattern
- 其对象表示通过编译的正则式,利用该类对象可以与任意字符串进行模式匹配
- 构造器
- Pattern类的构造器是private
- 声明
- public final class Pattern extends Object implements Serializable
- 创建Pattern的静态工厂
- public static Pattern compile(String regex)
- 将指定正则式编译成Pattern对象返回
- public static Pattern compile(String regex,int flags)
- 将指定正则式按照指定标志编译成Pattern对象返回
Pattern标志常量
- public static final int CASE_INSENSITIVE
- 将启动对ASCII字符不区分大小写匹配
- public static final int UNICODE_CASE
- 将启动Unicode字符不区分大小写匹配
- public static final int DOTALL
- 将启动dotall模式,该模式下,"."将表示任意字符,包括回车符
Pattern常用方法
- package com.itlwc;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- public class Test {
- public static void main(String[] args) throws Exception {
- // 编译好的模式用起来更快一些
- // 将给定的正则表达式编译到模式中
- Pattern p = Pattern.compile("[a-z]{3}");
- // 将给定的正则表达式编译到具有给定标志的模式中
- p = Pattern.compile("[a-z]{3}", Pattern.CASE_INSENSITIVE);
- // 返回此模式的匹配标志
- System.out.println(p.flags());
- // 匹配某个字符串之后的结果,这个有可能有很多个
- // 该方法返回表示将要被匹配字符序列的匹配器对象
- Matcher m = p.matcher("fgh");
- System.out.println(m.matches());
- // 编译给定正则表达式并尝试将给定输入与其匹配
- System.out.println(Pattern.matches("[a-z]{3}", "fgh"));
- // 返回在其中编译过此模式的正则表达式
- System.out.println(p.pattern());
- // 该方法返回指定字符串的模式文本表示
- System.out.println(Pattern.quote("abc"));
- // 匹配拆分
- String[] str1 = Pattern.compile(",").split("boo,and,foo");
- for (String s : str1) {
- System.out.print(s + " ");
- }
- System.out.println();
- // 匹配拆分,拆分几段
- String[] str2 = Pattern.compile(":").split("boo:and:foo", 2);
- for (String s : str2) {
- System.out.print(s + " ");
- }
- }
- }
- /*
- 打印结果:
- 2
- true
- true
- [a-z]{3}
- QabcE
- boo and foo
- boo and:foo
- */
Matcher概述
- java.util.regex.Matcher 匹配器
- 声明
- public final class Matcher extends Object implements MatchResult
Matcher常用方法
- package com.itlwc;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- public class Test {
- public static void main(String[] args) throws Exception {
- Matcher m1 = Pattern.compile("\d{3,5}").matcher("123-45682-152-00");
- // 返回由此匹配器解释的模式
- System.out.println(m1.pattern());
- // 只有整个字符序列完全匹配成功才返回true
- System.out.println(m1.matches());
- // 把原来吃点的吐出来恢复到从前的状态
- m1.reset();
- // 找一个和模式匹配的子串,找到之后正则表达式引擎会把第一个子串去掉
- System.out.println(m1.find());
- // 起始位置和结束位置,但必须能找到,否则报错
- System.out.println(m1.start() + "-" + m1.end());
- // 每次都从开始位置找
- System.out.println(m1.lookingAt());
- System.out.println("------------------------------");
- CharSequence cs = "java JAVA javaEE hiJAVA abcdefg";
- int i = Pattern.CASE_INSENSITIVE;
- Matcher m2 = Pattern.compile("java", i).matcher(cs);
- while (m2.find()) {
- // 分组,输出匹配到的子串
- System.out.print(m2.group() + " ");
- }
- System.out.println();
- System.out.println("------------------------------");
- // 把java全部替换成JAVA
- System.out.println(m2.replaceAll("JAVA"));
- System.out.println("------------------------------");
- // 把单数java转换为小写,双数java转换为大写
- m2.reset();
- StringBuffer sb = new StringBuffer();
- int count = 0;// 奇数偶数的常量
- while (m2.find()) {
- count++;
- if (count % 2 == 0) {
- // 替换
- m2.appendReplacement(sb, "JAVA");
- } else {
- m2.appendReplacement(sb, "java");
- }
- }
- // 添加尾巴,否则abcdefg不显示
- m2.appendTail(sb);
- System.out.println(sb);
- System.out.println("------------------------------");
- // 取符合正则表达式
- Pattern p = Pattern.compile("\d{3,5}[a-z]{2}");
- Matcher m3 = p.matcher("123aa-33345bb-234cc-00");
- while (m3.find()) {
- System.out.print(m3.group() + " ");
- }
- System.out.println();
- // 使用分组取数字,有几个(就分了几组
- // 怎么知道是第几组,规律是(是第几个就是第几组
- p = Pattern.compile("(\d{3,5})([a-z]{2})");
- m3 = p.matcher("123aa-33345bb-234cc-00");
- while (m3.find()) {
- // 只要第一组数字
- System.out.print(m3.group(1) + " ");
- }
- m3.reset();
- System.out.println();
- while (m3.find()) {
- // 只要第一组字母
- System.out.print(m3.group(2) + " ");
- }
- }
- }
- /*
- 打印结果:
- d{3,5}
- false
- true
- 0-3
- true
- ------------------------------
- java JAVA java JAVA
- ------------------------------
- JAVA JAVA JAVAEE hiJAVA abcdefg
- ------------------------------
- java JAVA javaEE hiJAVA abcdefg
- ------------------------------
- 123aa 33345bb 234cc
- 123 33345 234
- aa bb cc
- */
网页中揪出Email
- package com.itlwc;
- import java.io.BufferedReader;
- import java.io.FileReader;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- public class Test {
- public static void main(String[] args) throws Exception {
- FileReader fr = new FileReader("D:\email.html");
- BufferedReader br = new BufferedReader(fr);
- String line = "";
- while ((line = br.readLine()) != null) {
- parse(line);
- }
- }
- private static void parse(String line) {
- Pattern p = Pattern.compile("[\w[.-]]+@[\w[.-]]+\.[\w]+");
- Matcher m = p.matcher(line);
- while (m.find()) {
- System.out.println(m.group());
- }
- }
- }