正则表达式

来源:互联网 发布:印象笔记 mac无法同步 编辑:程序博客网 时间:2024/06/10 14:43


正则表达式(Regular Expression)是一个强大的字符串处理工具,可以对字符串进行查找、提取、分割、替换等操作。
正则表达式是一个非常实用的工具,用于匹配字符串的模版。
Java还提供了Pattern和Matcher两个类专门用于提供正则表达式的支持。

String类里提供了如下几个特殊方法:
boolean matches(String regex):判断该字符串是否匹配指定正则表达式。
String replaceAll(String regex, String replacement):返回该字符串中所有匹配正则表达式的子串替换成replacement后的新字符串。
String[] split(String regex):根据给定正则表达式拆分该字符串后得到的字符串数组。

上面这些特殊的方法都依赖于Java提供的正则表达式支持。

下面先列出一些常用的正则表达式的构造摘要。

      构造                            匹配
    --------------------------------------------
1)字符
      x                                  字符x  
      \\                              反斜线字符 

2)字符类
      [abc]                       a、b 或 c(简单类) 
      [^abc]                     任何字符,除了 a、b 或 c(否定) 
      [a-zA-Z]                  a 到 z 或 A 到 Z,两头的字母包括在内(范围) 

3)预定义字符类
     .                               任何字符(与行结束符可能匹配也可能不匹配) 
     \d                             数字:[0-9] 
     \D                            非数字: [^0-9] 
     \s                             空白字符:[ \t\n\x0B\f\r] 
     \S                            非空白字符:[^\s] 
     \w                            单词字符:[a-zA-Z_0-9] 
     \W                           非单词字符:[^\w] 

4)边界匹配器
     \b                            单词边界 
     \B                           非单词边界 

5)数量词
     X?                          X,一次或一次也没有 
     X*                           X,零次或多次 
     X+                          X,一次或多次 
     X{n}                        X,恰好 n 次 
     X{n,}                       X,至少 n 次 
     X{n,m}                    X,至少 n 次,但是不超过 m 次 

1.匹配
使用String类的方法matches(String regex)。
public class RegexDemo {public static void main(String[] args) {//字符串是否匹配邮箱格式String mail = "123yp@sina.com";String regex = "\\w+@[a-zA-Z]+(\\.[a-zA-Z]+){1,2}";System.out.println("该字符串是否符合邮箱格式:" + mail.matches(regex));}}

2.切割
使用String类的方法split(String regex)。

下面程序将一个绝对路径切割成几个分路径。
public class RegexDemo {public static void main(String[] args) {//将下面路径切割成分路径String path = "c:\\java\\day1\\Hello.java";//切割成分路径,即将反斜线作为分隔符切割成几部分//因为是双反斜线,每个反斜线都要用一个反斜线转义,所以正则表达式是"\\\\"String regex = "\\\\";String[] paths = path.split(regex);for(String p : paths){System.out.println(p);}}}


下面程序将ip地址分成4段
public class RegexDemo {public static void main(String[] args) {//将下面ip地址分段String ip = "192.168.10.10";//ip地址分段,即将点作为分隔符切割成几部分//因为在正则表达式中,点代表任意符号,所以要将点转义,而每个反斜线都要用一个反斜线转义,所以正则表达式是"\\."String regex = "\\.";String[] ips = ip.split(regex);for(String i : ips){System.out.println(i);}}}

下面程序将一个字符串以叠词为分隔符来进行切割
1)叠词就是多个连续的相同字母。
2)这里要用到正则表达式中组的概念,组用一对小括号表示,“()”,小括号中是每个组的规则。每个组都有编号。
获取组的个数与每个组其自身编号的技巧:出现多少个左括号“(”就有几个组,并且左括号出现的次数即为该组的编号,如:((())())中有4组。
3)在同一个正则表达式字符串中,使用“\\n”来表示第n个组的引用(“\n代表引用第n组,但是反斜线也要转义”)。而在不同表达式中,使用美元符号“&n”来表示引用前一个字符串中第n个组。

所以叠词的正则表达式写法:([a-zA-Z])\\1+。
[a-zA-Z]代表任意一个字符的引用;([a-zA-Z])代表将这个字符作为一个规则,变成一个组;\\1代表引用第1组的规则,即和前一个字符相同的字符;+代表出现一次或多次。
public class RegexDemo {public static void main(String[] args) {//将下面字符串使用叠词作为分隔符来切割String str = "abcdekkabcdqqfakcls";//叠词的正则表达式String regex = "([a-zA-Z])\\1+";String[] strs = str.split(regex);for(String s : strs){System.out.println(s);}}}

3.替换
使用String类的方法replaceAll(String regex, String replacement)。
public class RegexDemo {public static void main(String[] args) {//将下面语句变成“我要学编程”String str = "我我..要要.....学...学学学..编编编...编编...编编程...";//先将多余的省略号去掉str = str.replaceAll("\\.+", "");//将重复的字去掉//这里用到组的概念。每个任意的字为一个组//多个连续重复的字的正则表达式为"(.)\\1+"//替换成一个单一的字,即要引用前一个字符串中的组,用"$1"str = str.replaceAll("(.)\\1+", "$1");System.out.println(str);}}

4.获取
Java提供了Pattern和Matcher类来使用正则表达式。
Pattern对象是正则表达式编译后在内容中的表示形式,而Matcher对象代表执行匹配所涉及的状态保留在其中。
使用步骤:
1)将正则表达式封装成对象。
2)将正则对象和要匹配的字符串相关联。
3)关联后,获取匹配器。
4)通过匹配器对符合规则的子串进行操作。

Pattern类没有构造器。
方法:
static Pattern compile(String regex):返回Pattern对象,将给定的正则表达式编译到模式中。
Matcher matcher(CharSequence input):返回一个Matcher对象,将给定的正则表达式编译到具有给定标志的模式中。这个方法将正则表达式和字符串关联。

Matcher类,一般通过Pattern对象的matcher方法返回一个Matcher对象。
方法:
boolean matches():尝试将整个区域与模式匹配。即返回整个目标字符串与正则表达式是否匹配。
boolean find():尝试查找与该模式匹配的输入序列的下一个子序列。
String group():返回由以前匹配操作所匹配的输入子序列。与find方法一起使用。
int start():返回以前匹配的初始索引。
int end();返回最后匹配字符之后的偏移量。
public class RegexDemo {public static void main(String[] args) {//查找字符串中是3个字母组成的单词String str = "ming tian jiu yao fang jia la";//正则表达式,\b代表单词边界String regex = "\\b[a-zA-Z]{3}\\b";//将正则表达式封装成对象Pattern p = Pattern.compile(regex);//将正则表达式和字符串关联并获取匹配器Matcher m = p.matcher(str);//查找while(m.find()){System.out.println(m.group());}}}



练习1.  将字符串中的ip地址按分组顺序排序
public class RegexDemo {public static void main(String[] args) {//按字符串的比较来判断String ip = "192.168.0.1 10.10.10.10 8.30.5.7 102.49.7.89 2.2.2.2";//在每个ip地址段前补两个零,使得每段地址至少为3位ip  = ip.replaceAll("(\\d+)", "00$1");System.out.println(ip);//将每段地址多余的0去掉,使得每段地址只有3位ip = ip.replaceAll("0+(\\d{3})", "$1");System.out.println(ip);//将ip地址切割成为一个单独的ip地址String[] ips = ip.split(" ");//遍历数组//将数组元素按照字符串的自然顺序将其存到TreeSet中,这样也就进行了按自然顺序的排序TreeSet<String> set = new TreeSet<String>();for(String i : ips){set.add(i);}//将每段地址前面多余的0去掉并打印for(String i : set){System.out.println(i.replaceAll("0+(\\d+)", "$1"));}}}


练习2   网页爬虫:获取某网页所有邮箱地址。
public class RegexDemo {public static void main(String[] args) throws Exception{//获取网页链接URL url = new URL("http://book.douban.com/subject/3072831/discussion/1295004/");URLConnection conn = url.openConnection();//输入流BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));//邮箱地址正则表达式String regex = "\\w+@[a-zA-Z]+(\\.[a-zA-Z]+){1,2}";//将正则表达式封装成对象Pattern p = Pattern.compile(regex);String line = null;while((line = in.readLine()) != null){//将正则表达式与字符串相关联Matcher m = p.matcher(line);//查找while(m.find()){System.out.println(m.group());}}}}



0 0
原创粉丝点击