Logo

郎哥编程

正则表达式

2019-12-10 837

正则表达式通常被用来处理文本,在文本处理领域应用非常广泛。本课通过邮箱地址格式验证案例,让读者对正则表达式有个初步认识,要深入掌握正则表达式,还需要专门学习正则表达式的课程。

为啥说我邮箱地址格式不对呢?

当您在一个网站或者客户端程序中,要注册一个新的用户时,网站或客户端程序可能会要求输入您的邮箱地址。也许您不想让网站或客户端程序知道您的邮箱地址,或者嫌输入麻烦,您会随便输入一段字符串,希望蒙混过关。可惜的是当您提交录入的注册信息时,网站或客户端程序会告知您输入的邮箱地址格式错误。网站或客户端程序是如何来判断您输入的邮箱地址格式是错误的呢?

原来是正则表达式在起作用

这就要说到正则表达式了,正则表达式可以使用一些预定义的字符、符号以及这些字符或符号的组合,组成一个规则串,然后使用这个规则串对需要处理的一段字符串进行匹配。如果这段字符串的内容和规则串能够匹配,则匹配成功,否则就匹配失败。正则表达式被经常使用在数据采集、搜索引擎、编译系统、文本编辑器等方面。

正则表达式是由一些预定义的字符以及这些字符组合而成的字符串。关于这些预定义的字符以及组合方式,暂时先不用全部了解其含义及用法,我们会在正则表达式的使用过程中,来逐步了解它们的含义及用法。

先来一个简单的正则表达式

假如您要使用Java开发一个用户注册程序,需要验证用户输入的邮箱地址格式是否正确,哪该怎么编写这个程序呢?

要验证邮箱地址的格式是否正确,需要先弄清楚邮箱地址的格式规则,有了邮箱地址的格式规则,就可以编写正则表达式了。观察邮箱地址,我们发现每个邮箱地址都包含“@”字符。

只有检测给出的邮箱地址是否包含“@”字符,就可以基本确定邮箱地址格式是否正确。如何判断一个字符串是否包含“@”字符呢?在Java语言中,可以使用字符串查找运算来判断是否包含“@”字符,不过在这里我们使用正则表达式来检测。

正则表达式就是一段字符串,这段字符串由一些预定义的字符、符号以及这些字符或符号组合而成。

我们先来认识预定义符号“[]”,这个符号是中括号,在中括号内可以包含一个或多个字符、符号构成的集合,当需要匹配的字符串包含中括号内的任意一个字符时,匹配就成功。

例如:匹配一个邮箱地址是否包含“@”符号,可以使用下面的正则表达式:

pattern = “[@]”

pattern是一个最简单的正则表达式,它使用了预定义的“[]”符号,在“[]”符号内包含一个“@”字符,使用该正则表达式可以匹配包含“@”字符的字符串,也可以用于检测邮箱地址是否包含“@”字符。

Java如何执行正则表达式?

Java提供了Pattern类用于执行正则表达式。Pattern类提供了matches()静态方法,该方法尝试从字符串的起始位置开始匹配,若匹配成功返回true,否则返回false。

matches()方法参数如下表所示:

image.png

下面的代码使用matches()方法检测邮箱地址是否包含“@”字符,可以猜想一下,使用下面的代码能检测成功吗?

String pattern = "[@]";
boolean isMatch = Pattern.matches(pattern, "'bianchen@163.com");
System.out.println("字符串中是否包含了 '@' 字符? " + isMatch);

上面的代码pattern是正则表达式,使用Pattren类的matches()方法匹配邮箱地址bianchen@163.com,验证邮箱地址是否包含“@”字符。前面说过,matches()尝试从字符串的起始位置开始匹配,如果在起始位置匹配不成功的话matches()返回false。邮箱地址这个字符串起始位置不是“@”字符,因此会匹配失败,程序执行结果也是如此。下图是上述代码的执行结果:

image.png                                             

这次要动真格的了,写一个比较复杂的正则表达式

观察下面的邮箱地址:

bianchen@163.com
johy_1996820@yahoo.com
89299001@qq.com

每个邮箱地址都符合“名称@域名”规则,字符“@”在邮箱地址的“名称”和“域名”之间。进一步观察发现,邮箱地址名称只允许由英文字母、数字、下划线组成,当然现在也允许包含中文了,关于中文暂时不予考虑;域名只允许由英文字母、数字、下划线、“.”组成。

基于上述观察,在写正则表达式时,可以在符号“@”前面匹配任意多个符合邮箱名称规则的字符和符号,在符号“@”后面匹配任意多个符合邮箱域名规则的字符和符号。

下面给出的正则表达式可以验证邮箱地址格式的正确性:

pattern = "\w+[@][a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)"

这段正则表达式比前面的正则表达式复杂了许多,是不是感觉不太容易理解,这一长串字符和符号的组合都有什么含义呢?

首先,我们以字符串“[@]”为分隔串将正则表达式分为两部分。

第一部分是:

“\w+”

第二部分是:

“[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)”

第一部分是匹配邮箱名称,前面说过邮箱名称由英文字母、数字、下划线组成。在正则表达式中,使用“\w”来匹配数字、字母和下划线,“\W”来匹配非数字、字母和下划线。

类似于“\w”、“\W”这种字符组合在正则表达式中也称为元字符,前面介绍的“[]”也是正则表达式的元字符,元字符使正则表达式具有处理能力。例如:“\w”元字符可以让正则表达式具备匹配数字、字母和下划线的能力。

元字符“\w”仅匹配单个数字、字母和下划线,如果需要匹配多个数字、字母和下划线,就需要用到正则表达式的元字符“+”,元字符“+”可以让前面的字符或子表达式匹配一次或多次。例如:“\w+”子表达式就具备匹配一个或多个数字、字母和下划线的能力。

第二部分是匹配邮箱域名,邮箱域名由英文字母、数字、下划线、“.”组成,和邮箱名称的构成基本相同。域名结构分为前缀和后缀两部分,在前缀和后缀之间用“.”分隔。 “[a-zA-Z0-9_-]”表示匹配’a’-‘z’范围内的小写字母、’A’-‘Z’范围内的大写字母、数字0-9、下划线。“[a-zA-Z0-9_-]”等同于元字符“\w”。“[a-zA-Z0-9_-]+”等同于“\w+”。

“(\.[a-zA-Z0-9_]+)”是子表达式,子表达式内容使用一对小括号括起来,一对小括号也是正则表达式的元字符。括号内的“\.”用于匹配邮箱域名的“.”,其中元字符“\”是转义元字符,它把元字符后面的字符标记为特殊字符、文本等。例如:“\.”匹配单符号“.”,“\n”匹配单字符“n”。“[a-zA-Z0-9_]+”就不用解释了。

案例1:使用正则表达式验证给出的邮箱地址格式是否正确。

在PbaseUnit11项目unit包下创建RegularSample类。代码如下:

/** 
* @Title: RegularSample.java 
* @Package unit 
* @Description:Java基础知识课程案例    
* @author 编程训练营 
* @date 
* @version V1.0 
*/ 
 
package unit;
 
import java.util.regex.Pattern;
 
/** 
* @ClassName: RegularSample 
* @Description: 字符串(正则表达式)案例1
* @author 编程训练营 
* @date 
* 
*/
 
public class RegularSample {
 
    /** 
    * @Title: main 
    * @Description: Java程序入口main方法
    * @param @param args    参数 
   
    * @return void    返回类型 
    * @throws 
    */
 
    public static void main(String[] args) {
        // 验证邮箱地址格式的正则表达式
       String pattern = "\\w+[@][a-zA-Z0-9_]+(\\.[a-zA-Z0-9_]+)";
       /**
        *  Pattern类在java.util.regex包内
         *    使用import语句导入java.util.regex.Pattern
        *  matches()方法是静态方法,用类名可以直接调用
        */
        boolean isMatch = Pattern.matches(pattern, "bianchen@163.com");
        if( isMatch )
            System.out.println("bianchen@163.com 格式正确");
        else
           System.out.println("bianchen@163.com 格式错误");
    }
 
}

程序结构分析

Pattern类在java.util.regex包内,需使用import语句导入。Pattren类的matches()方法是静态方法,用类名可以直接调用。

matches()方法使用pattern模式来匹配给出的邮箱地址,如果邮箱地址符合pattern模式,matches()方法返回true,说明邮箱地址格式正确。

判断邮箱地址格式还有点小问题

修改一下上面的代码,将待验证的邮箱地址修改为:

bianchen@wy.163.com

待验证的邮箱地址域名分为一级和二级域名,执行程序看是否还能匹配成功。执行结果如下图所示:

image.png


从执行结果可以看出,邮箱地址匹配失败。问题在于“(\.[a-zA-Z0-9_]+)”仅匹配一次域名的后缀,如果邮箱域名有多个域名后缀则只能匹配最前面一个。要解决这个问题,就需要“(\.[a-zA-Z0-9_]+)”重复匹配一次或多次,前面说过,正则表达式的元字符“+”可以让前面的字符或子表达式匹配一次或多次,在“(\.[a-zA-Z0-9_]+)”后面添加元字符“+”,就可以实现重复匹配一次或多次。修改案例1代码的正则表达式:

String pattern = "\\w+[@][a-zA-Z0-9_]+(\\.[a-zA-Z0-9_]+)+";

程序执行结果如下图所示:

image.png


从执行结果可以看出,邮箱地址匹配成功。

小结一下文中正则表达式用到的元字符和文本字符

元字符

image.png

 

文本字符

 image.png

 


代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论