Java正则表达式

来源:互联网 发布:中国投资咨询公司 知乎 编辑:程序博客网 时间:2024/05/17 22:17

正则表达式是处理字符串的强大的工具,它不是Java的特性,前端的JavaScript等也有。但是相比于其他老牌的高级语言,如C/C++,这是Java比他们独特的地方。

入门案例

首先来看一个需求:
一些网站设定了一些制定密码的规则。编写一个方法,检验一个字符串是否合法的密码。假设密码规则如下:

 1.密码必须至少有8个字符。 2.密码只能包括字母和数字。 3.密码必须至少有2个数字。 编写一个程序,提示用户输入密码,如果该密码符合规则就显示“合法密码”,否则显示“不合法密码”

不用正则表达式之前,我们可以这样解决:

import java.util.Scanner;/* * 功能:检测密码的合法性 * 日期:2016.11.19 *  */public class RegexDemo {    public static void main(String[] args) {        Scanner input = new Scanner(System.in);        String password = input.nextLine();        if(true == isValid(password)) {            System.out.println("合法密码格式");        } else {            System.out.println("不合法密码格式");        }    }    public static boolean isValid(String password) {        if(password.length() < 8) {            return false;        } else {            int numberCounter = 0;            for(int i = 0; i < password.length(); i++) {                char c = password.charAt(i);                if(!Character.isLetterOrDigit(c)) {                    return false;                }                if(Character.isDigit(c)) {                    numberCounter++;                }            }            if(numberCounter < 2) {                return false;            }        }        return true;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

这个算法还不是特别的繁琐,稍微耐性点就会解决。然而正则表达式即将登上舞台,它的诞生就是专为了治理字符串这种的疑难杂症。在正则表达式正式出场之前,我们先从熟悉的String类两个方法开始。

返回值 方法头 String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串。 String[] split(String regex, int limit) 根据匹配给定的正则表达式来拆分此字符串。

这是String类自带的方法,方法里面的参数是一个正则表达式,比如我想把一个带有ip和端口的ip v4地址分割出来,那么用法如下:

public static void main(String[] args) {    String ip = "127.0.0.1:80";    String[] ips = ip.split(":");    System.out.println("IP地址:" + ips[0]);    System.out.println("端口号:" + ips[1]);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

split()里面的”:”就是一个最简单的正则表达式,下面分别从正则表达式的匹配、替换、分割和获取来了解JAVA正则。

匹配

匹配数字案例,用正则表达式来判断字符串中是否全部是数字:

String str = "123456789";String reg = "\\d+";boolean b= str.matches(reg);System.out.println(b);
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

其中\d是正则表达式的匹配模式,在java中\代表转义符,所以这里\d应该写成”\d”,后边的+是量词,代表前面的匹配出现的次数是一次或多次。其量词类型如下图所示:
这里写图片描述

匹配手机号码,匹配规则:手机号码必须是11位数,而且必须是13、15、18开头。

String tel = "13628123409";String telReg = "1[358]\\d{9}";System.out.println(tel.matches(telReg));
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

正则变量telReg的表达式中,”1”表示第一位只能是数字1,[358]表示第二位的之可以取”358”中的任意一个,”{9}”表示\d有9位,也就是说数字有几位。

切割

String str = "李彦宏.马云.马化腾";String reg = "\\.";String[] arr = str.split(reg);  System.out.println("切割得到的长度是:" + arr.length);for(final String s : arr) {    System.out.println(s);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

上诉的正则将字符串中以”.”为界限进行切割,得到一个字符串数组,切割得到的字符串放进字符串数组的元素中,下标从0开始。如上所述,输出的结果是:

切割得到的长度是:3李彦宏马云马化腾
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

如果字符串是以空格隔开,那么用的正则如下:

String reg = " +";
  • 1
  • 1

空白字符一般喜欢用\s来代替,所以如果是空格隔开,那么最好的用法如下:

String rege = "\s+";
  • 1
  • 1

匹配规则表如图:
这里写图片描述
完整的api文档你应该参考:java.util.regex 包下的Pattern类。

如果理解了上面的例子,还想挑战一下稍有难度的需求,那么请看:
把一个二维数组放在字符串里面,从字符串中提取出一个二维数组出来,保存在一个二维数组里面.

输入:
“1, 2; 3, 4, 5; 6, 7, 8, 9”(一个三行列不固定的二维数组,且这个二维数组是在字符串中)

输出:
1.0 2.0
3.0 4.0 5.0
6.0 7.0 8.0 9.0

解题思路:
先用“;”切割字符串,编程一维字符串数组,然后再遍历得到的一维字符串数组,依次将里里面的字符串再次用”.”来切割。具体的实现代码如下:

class StringToArray {    public static void main(String[] args) {        String str = "1, 2; 3, 4, 5; 6, 7, 8, 9";        String[] ss = str.split(";");        for(int i = 0; i < ss.length; i++) {            ss[i] = ss[i].trim();        }        //已经将字符串划分到了一个一维数组里面        //接下来就是每组分别分割成double型的数        double[][] arr = new double[ss.length][];        for(int i = 0; i < ss.length; i++) {            String[] ssChildren = ss[i].split(",");            arr[i] = new double[ssChildren.length];            for(int j = 0; j < ssChildren.length; j++) {                ssChildren[j] = ssChildren[j].trim();                arr[i][j] = Double.valueOf(ssChildren[j]);            }        }        //已经把字符串中的数字都放在二维数组里面了,现在输出        for(int i = 0; i < arr.length; i++) {            for(int j = 0; j < arr[i].length; j++) {                System.out.print(arr[i][j] + "\t");            }            System.out.println();        }    }   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

切割重叠词,将叠词两边的字符串分割出来:

 String str = "erkktyqqquizzzzzo"; String reg = "(.)\\1+"; String[] arr = str.split(reg);   System.out.println("切割得到的长度是:" + arr.length);    for(final String s : arr) {        System.out.println(s);    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

将规则封装成一个组。用()完成。组的出现都有编号。从1开始。 想要使用已有的组可以通过 \n(n就是组的编号)的形式来获取。

替换

有这么一个字符串”wer1389980000ty1234564uiod234345675f”,将字符串中的数组替换成#。

public static void replaceAllDemo(String str,String reg,String newStr) {    str = str.replaceAll(reg,newStr);    System.out.println(str);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
replaceAllDemo(str,"\\d{5,}","#");
  • 1
  • 1

操作的步奏是,正则先去匹配字符串,如果找到匹配则替换。

替换叠词,将重叠的字符替换成单个字符,如:tt->t,调用的方法还是如上,传递的字符串和正则规则如下:

String str1 = "寻寻觅觅冷冷清清,凄凄惨惨戚戚,乍暖还寒时候,最难将息";replaceAllDemo(str1,"(.)\\1+","$1");
  • 1
  • 2
  • 1
  • 2

</span>RegExpMultiline也匹配“\n”或“\r”之前的位置。李清照的这句词将被分割成”寻觅冷清,凄惨戚,乍暖还寒时候,最难将息”。

获取

正则表达式的第四个功能:获取。将字符串中的符合规则的子串取出。这里必须去了解和使用JAVA封装的两个类:Matcher,Pattern。

String str = "Hello Rgex This is the test text!";System.out.println(str);String reg = "\\b[a-z]{4}\\b";//将规则封装成对象。Pattern p = Pattern.compile(reg);//让正则对象和要作用的字符串相关联。获取匹配器对象。Matcher m  = p.matcher(str);System.out.println(m.matches());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

其实String类中的matches方法。用的就是Pattern和Matcher对象来完成的。只不过被String的方法封装后,用起来较为简单。但是功能却单一。

public class RegexDemo {    public static void main(String[] args) {        getDemo();    }    public static void getDemo(){        String str = "Hello,Rgex,This,is,the,test,text!";        System.out.println(str);        String reg = "[a-zA-Z]{2,4}";        //将规则封装成对象。        Pattern p = Pattern.compile(reg);        //让正则对象和要作用的字符串相关联。获取匹配器对象。        Matcher m  = p.matcher(str);        while(m.find()) {            String result = m.group();            System.out.println(result);        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

操作步骤:
1,将正则表达式封装成对象。
2,让正则对象和要操作的字符串相关联。
3,关联后,获取正则匹配引擎。
4,通过引擎对符合规则的子串进行操作,比如取出。

(function () {('pre.prettyprint code').each(function () { var lines = (this).text().split(\n).length;varnumbering = $('
    ').addClass('pre-numbering').hide(); (this).addClass(hasnumbering).parent().append(numbering); for (i = 1; i
    原创粉丝点击