正则表达式

来源:互联网 发布:uefi硬盘安装ubuntu 编辑:程序博客网 时间:2024/06/05 03:28

一、简介

JDK1.4之后专门引入了一个java.util.regex开发包,这个包中有两个主要类负责完成正则的开发:Pattern(定义并且编译正则的匹配模版)和Matcher(匹配应用)。在一般的开发中,很少再直接使用这两个类了,主要是因为在JDK1.4之后对String类的修改达到了一个很好的正则操作效果,主要使用String类完成。

二、正则表达式(RegularExpression)

是一种描述字符串集的通用标准,它是以字符串集中各字符串的共有特征为依据的。正则表达式提供了一种紧凑的、动态的语言,它能够以一种完全通用的方式来解决各种字符串处理问题。正则表达式最早出现于perl,目前,各操作系统及大部分程序设计语言都支持正则表达式。

正则表达式主要用于:

搜索与替换:特定模式字符串的查找与替换。

验证:检查某个字符串是否符合特定的匹配模式。如E-mail地址,HTTP地址、FTP地址、身份证号码的验证。

解析:从一个文本中获取有用的字符串信息,如从HTML文件中提取超链接。

模式

模式(pattern)是正则表达式的重要组成部分,其规定了正则表达式的匹配法则和规范。正则表达式常用的定义元素有:

元字符

字符类

转义字符

限定符

反义

逻辑或

分组

1.      元字符:元字符(Meta Character)是能够匹配一个位置或某个字符串的一个字符。元字符分为两类:匹配位置的元字符和匹配字符的元字符。

匹配位置的元字符及作用如下表

字符

作用

示例

^

指示从行的开始位置进行匹配

如:^java匹配以“java”开始的行

$

指示从行的结束位置开始匹配

如:^java$匹配以“java”开始或结尾的行

\b

匹配单词的开始或结束位置

如:\bjava匹配以“java”开始的字符串,而”java”之前必须是单词的分界处

匹配字符的元字符有7个,作用如下:

字符

作用

示例

.

匹配除换行符以外的任意字符

如:^..c匹配第三个字符是c的行

\w

匹配单字字符(a~z,A~Z,0~9及下画线)

如:^..\w匹配第三个字符是单字字符的行

\W

匹配非单字字符

如:^..\W匹配第三个字符不是单字字符的行

\s

匹配空白字符(如空格、制表符、换行符等)

如:^..\s匹配第三个字符是空白字符的行

\S

匹配非空字符

如:^..\S匹配第三个字符不是空白字符的行

\d

匹配数字字符(0~9)

如:^..\d匹配第三个字符是数字字符的行

\D

匹配非数字字符

如:^..\D匹配第三个字符不是数字字符的行

2.      字符类

元字符只能匹配一个位置或字符合集中的一个字符,如果要匹配字符集合(如[0,1,2,3,4])时,则需要定义匹配的字符集合。字符类就是括号中的一个字符集,只匹配括号内的任意字符。

下述正则表达式匹配HTML文本中的<H1>、<H2>、<H3>、<H4>或<H5>

<H[12345]>

在使用字符类进行匹配时,对于连续的字符(如:a~z A~Z,0~9等),如果全在括号中列举很不方便,此时可以使用范围符“-”来定义字符的范围,如上面正则表达式等同于<H[1-5]>

而对于8位的电话号码可以定义为:\b[0-9]0-9[0-9][0-9][0-9][0-9][0-9]0-9[0-9][0-9]\b

3.      转义字符:对于诸如“^”“$”这样的字符都有特殊意义,如果需要在正则表达式中匹配字符串中的“^”“&”等字符时,则需要使用转义字符“\”(反斜杠)来解决这一问题。

如:www\.baidu\.com可以匹配www.baidu.com

常用的转义字符有:.、$、^、{、[、|、]、*、+、?、\,除上述字符外其它的字符都不需要转义。

4.      限定符:

一个元字符只能匹配一个字符,如果需要匹配零个、一个或多个字符时,可以使用限定符。限定服用于指定允许特定字符或字符集自身重复出现的次数。有*,+,?,{n},{n,}和{n,m}共6种

限定符

作用

示例

*

匹配前面的子表达式零次或多次

如:zo*能匹配“z”“zoo”*等价于{0,}

+

匹配前面的子表达式一次或多次

如:zo+能匹配”zo”及”zoo”但不能匹配”z”  +等价于{1,}

?

匹配前面的子表达式零次或一次

如:do[es]?能匹配“do”或“does”中的”doe”,?等价于{0,1}

{n}

匹配确定的n次,n是一个非负整数

如:o{2}能匹配“food”中的两个“oo”

{n,}

至少匹配n次,n是一个非负整数

如:o{2}能匹配“fooood”中的所有”o”,但不能匹配“Tom”中的”o”o{1,}等价于o+

{n,m}

至少匹配n次,至多匹配m次,n和m是一个非负整数,其中n<=m

如:o{1,3}将匹配“fooood”中的前三个“o”。o{0,1}等价于o?

引入限定符后对于8位的电话号码可以定义为:\bd{8}\b

下述正则表达式限制数字型字符串的整数位最多为3位,小数位为两位:^d{0,3}\.\d{2}\b

如果在限定符之后再添加一个字符“?”,则表示尽可能少的重复字符“?”之前的限定符号重复次数,此种匹配方式称为懒惰匹配。如果不加“?”则默认为贪婪匹配,即匹配最长的字符串。

以下正则表达式匹配以字母a开头以字母b结尾的最长字符串:a.*b;

以下正则表达式匹配以a开头以b结尾的最长的字符串:a.*?b;

5.      反义

在使用正则表达式时,如果需要匹配不在字符集指定范围内的字符时,可以使用反义字符“^”(脱字符)进行声明。

6.      逻辑或“|”

7.      分组“(”     “)”。下述表达式可以匹配IP(IPv4)地址:(\d{1,3}\.){3}\d{1,3}

常用正则表达式

1.手机号码验证:目前国内的手机号码是以13,18,158或159开头,长度为11位的数字型字符串:\b0?(1[38]\d{9})|(15[89]\d{8})\b

2.身份证号码验证:中国境内公民身份证为15位或18位,从左至右为:6位地址码,6位或8位出生日期,3位顺序码和一位校验码(18位身份证)。

15位身份证验证:^\d{8}((0\d)|(1[0-2]))((3[01])|([0-2]\d))\d{3}$

18位身份证验证:^\d{6}((1[89])|(2\d))\d{2}((0\d)|(1[0-2]))((3[01])|([0-2]\d))\d{3}(\d|x)$

E-mail验证:\w+@\w+(\.\w+)+

在Java中使用正则表达式

在Java中使用正则表达式需要引入java.util.regex包。

一个正则表达式编译成为一个Pattern类的对象,这个Pattern的对象通过调用matcher()方法来产生一个Matcher对象,然后通过Matcher实例编译正则表达式,从而对目标字符串进行匹配工作。

Pattern类

Pattern表示一个已经编译的正则表达式。Pattern类没有提供公共的构造方法,要构建一个模式,首先必须调用公共的静态的compile()方法,它将返回一个Pattern对象。

Matcher类

Matcher类是一个依靠输入的字符串来解析这个模式和完成匹配操作的对象。与Pattern类似,Matcher也没有定义公共的构造方法,需要通过调用Pattern对象的matcher方法来获得一个Matcher对象。

应用实例

基于Java,使用正则表达式的一般步骤是:

01构造一个Pattern对象,如:

Patternpattern = Pattern.compile(“[a-z]*”);

02构造一个Matcher对象,如:

Matchermatcher = pattern.matcher(str);

03根据匹配结果进行判断、替换、查找等操作,如:

Boolean flag= matcher.matches();

import java.util.regex.Matcher;import java.util.regex.Pattern;public class RegexDemo {public static final String MESSAGE = "{0}, 恭喜你 {1}";public static void main(String[] args) {replace();validate();}/** * 字符或字符串替换:将消息模版中的0位置替换成"小明",1位置替换成"获得一等奖!" */public static void replace(){String[] replacements = {"小明" , "获得一等奖!"};Pattern p = Pattern.compile("\\{\\d\\}"); Matcher m = p.matcher(MESSAGE); StringBuffer sb = new StringBuffer(); int count = 0; while (m.find()) {     m.appendReplacement(sb, replacements[count]);     count++; } m.appendTail(sb); System.out.println(sb.toString());}/** * 密码校验:必须以大写字母开头,只能使用字母或数字、点以及下划线,长度不能少于6不能大于16 */public static void validate(){String password = "Abc123.D_D";Pattern pattern = Pattern.compile("[A-Z][\\w.]{5,15}");Matcher matcher = pattern.matcher(password);Boolean flag = matcher.matches();System.out.println(flag);//true}}

三、String类对正则表达式的支持

NO

方法

描述

1

Public Boolean matches(String regex)

与指定正则匹配

2

Public String replaceAll(String regex, String replacement)

替换满足指定正则的全部内容

3

Public String replaceFirst(String regex,String replacement)

替换满足指定正则的首个内容

4

Public String[] split(String regex)

按照指定正则全拆分

5

Public String[] split(String regex,int limit)

按照指定的正则拆分为指定个数

范例:

将字符串中的字母消除:

public class RegexTest1 {public static void main(String[] args) {String str = "a1b2ccc3dddddddd4e5f6s7fsd8sdfsd9sdfsdf0sdf";String regex = "[a-zA-Z]*";System.out.println(str.replaceAll(regex, ""));//替换全部System.out.println(str.replaceFirst(regex, ""));//替换首个}}

字符串按照数字拆分:

public class RegexTest1 {public static void main(String[] args) {String str = "a1b2ccc3dddddddd4e5f6s7fsd8sdfsd9sdfsdf0sdf";String regex = "\\d";String[] result = str.split(regex);for(String st : result){System.out.print(st + " , ");}}}

结果:

a , b, ccc , dddddddd , e , f , s , fsd , sdfsd , sdfsdf , sdf ,

简单的验证:要求字符串格式“aaaaab”,在b之前可以有任意个a,但是不能没有,至少一个

public class RegexTest1 {public static void main(String[] args) {String str = "aaaaaaaab";String regex = "a+b";//1个或多个a和1个bSystem.out.println(str.matches(regex));//正则验证}}

结果:true

验证一个字符串是否是整数类型,如果是将其变为int型数据,而后执行乘法操作。

import java.util.Scanner;public class RegexTest1 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String str = sc.nextLine();String regex = "[0-9]+";int mul = 0;boolean res = str.matches(regex);if(res){mul = Integer.parseInt(str)*Integer.parseInt(str);System.out.println(mul);}else{System.out.println("输入的不是数字");}}}

验证字符串是否是小数,如果是,则将其变为double型数据,而后执行乘方操作:

public class RegexTest1 {public static void main(String[] args) {System.out.println("请输入");Scanner sc = new Scanner(System.in);String str = sc.nextLine();String regex = "[0-9]+(.\\d+)?";double mul = 0;boolean res = str.matches(regex);if(res){mul = Double.parseDouble(str)*Double.parseDouble(str);System.out.println(mul);}else{System.out.println("输入的不是小数");}}}

说明:对于小数而言,小数点之后必须存在数字才有意义,所以使用了括号,表示整体出现0次或1次。

输入一个字符串,按照“年-月-日 时:分:秒”的形式,如果正确,则将其变为Date型数据
public class RegexTest2 {public static void main(String[] args) throws Exception {System.out.println("请输入");Scanner sc = new Scanner(System.in);String str = sc.nextLine();String regex = "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d{3}";boolean res = str.matches(regex);if(res){Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(str);System.out.println(date);}else{System.out.println("输入的不是日期形式");}}}
一个用户名只能由字母、数字、_组成,其长度只能是6~15位:
public class RegexTest3 {public static void main(String[] args) {System.out.println("请输入用户名");Scanner sc = new Scanner(System.in);String str = sc.nextLine();//String regex = "([a-z]|[A-Z]|[0-9]|_){6,15}";String regex = "\\w{6,15}";boolean res = str.matches(regex);if(res){System.out.println("验证通过");}else{System.out.println("用户名不合法");}}}
验证电话号码是否符合格式:

importjava.util.Scanner;/* * 验证电话号码是否符合格式:电话号码的格式:格式一:2502376              \\d{7,8}格式二:06322506372          (\\d{3,4})?\\d{7,8}格式三:0632-2502376         (\\d{3,4})?-?\\d{7,8}格式四:(0632)2502376       ((\\d{3,4}|\\(\\d{3,4}\\))-?)?\\d{7,8}格式五:(0632)-2502376  */public class RegexTest4 {    public static void main(String[] args) {        System.out.println("请输入电话号码");        Scanner sc = new Scanner(System.in);        String str = sc.nextLine();        String regex = "((\\d{3,4}|\\(\\d{3,4}\\))-?)?\\d{7,8}";        boolean res = str.matches(regex);        if(res)        {            System.out.println("验证通过");        }else{            System.out.println("电话号码不合法");        }    }}
验证邮箱的合法性:Email地址的用户名由字母、数字、_和.组成,其中不能以数字和.开头,而且Email的域名只能是.com、.cn、.net

public class RegexTest5 {    public static void main(String[] args) {        System.out.println("请输入邮箱");        Scanner sc = new Scanner(System.in);        String str = sc.nextLine();        String regex = "[a-zA-z][a-zA-Z_0-9\\.]{5,14}@[a-zA-Z_0-9\\.]+\\.(com|cn|net)";        boolean res = str.matches(regex);        if(res)        {            System.out.println("验证通过");        }else{            System.out.println("邮箱不合法");        }    }}

0 0