正则表达式

说到正则表达式,说起来其实老早就接触过了,但是从来没有系统地学习,最近在工作中编写shell脚本常常会遇到,看来有必要系统地学习一下。
首先什么是正则表达式,先来一段百科定义:“正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,模式描述在搜索文本时要匹配的一个或多个字符串。”
重点是我们应该知道它能用来干嘛:检索、替换某些符合某个规则的文本,简单来说,举几个应用场景:我们在网站注册时,输入个人信息如手机号、身份证号码或者邮箱时,一般来说都会有这样输入过滤,比如三大运营商的手机号必须是11位且以1开头;比如身份证号码是18位;邮箱格式example@example.com等。如果不满足这些条件红线警告,提示用户重新输入。这是正则表达式的一个常见且典型的应用。又或者是关键词过滤,提取一段文本中我们需要的信息,如提取链接,提取注释等等。看到这里有人会觉得这不就是查找吗,严格来说,是模糊匹配,也就是like和is的区别。
其次是正则表达式的重要性,其实上面几个例子已经很直观了,比如对于用户输入,如果不加过滤,任凭用户输入啥都提交,那么数据库岂不成了垃圾堆?当然,代码说话,如果给你一个字符串,判断是否是数字,返回true还是false。我们先看传统的写法,输入一个字符串,获取长度,遍历,如果有数字则遍历结束,返回true;否则继续直到遍历结束返回false。
先看传统写法

1 public static boolean isNumeric(String str){
2    for (int i = 0; i<str.length();i--;){  
3        if (!Character.isDigit(str.charAt(i))){
4            return false;
5        }
6    }
7    return true;
8 }

用正则表达式

public static boolean isInteger(String str) {  
        Pattern pattern = Pattern.compile("[0-9]*");  
        return pattern.matcher(str).matches();  
  }

是不是简单粗暴很多?不过我们需要明白这个”[0-9]*”究竟是何用意。
最后介绍正则表达式规则。
(1)元字符

符号说明
.匹配除换行符以外的所有字符
\w匹配字母或数字或下划线或汉字
\s匹配任意的空白符
\d匹配数字
\b匹配单词的开始或结束
^匹配字符串的开始
$匹配字符串的结束

Eg:
\b\w{5}\b 匹配刚好5个字符的单词。
^\w{5}$ 匹配刚好5个字符的字符串。
(2)重复

符号说明
*重复零次或更多次,即>=0
+重复一次或更多次,即>=1
?重复0次或1次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次,n<=m

Eg:
^\d{8,10}$: 匹配一个长为8到12位且只包含数字的字符串。
\d+:匹配一串数字,无论几位。
(3)字符转义
其实上面看到的”\”就是转义字符,当计算机遇到”\”就知道后面的字符需要特殊处理,比如”\d”,正是因为有了”\”,计算机才没有将”\d”当成”d”处理。那么问题来了,我想要查找”^”、” * “、”+”、”$”等本来就有特殊含义的字符时,怎么办呢?当然是用”\”进行转义,如” \ * “将被转义成字符” * “。所以这里有一个疑惑解决了,我们经常会看见D:\ \ Users这个路径,那么实际上便表示D:\ Users。
(4)字符类
由上面知道,我们想查找是不是数字或者是不是字母很简单,\d或者\w。但是如果我想匹配某一类数或者某一类字母呢,比如我想匹配1到5这些数字而不是全部呢?那么便引入了”[ ]”,如[1-5]表示匹配12345中的任意一个数字,如[aeiou]就匹配任何一个英文元音字母。
(5)分枝条件
正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开,需要注意的是一旦满足 | 左边的条件时,右边的条件将不再检验。
比如电话号码区号,假如左右用 - 隔开,- 左边可以是三位数字或者四位数字,右边均为五位,也就是说 XXX-XXXXX或者XXXX-XXXXX均要匹配,那么运用分枝条件,\d{3}-{5}|\d{4}-{5}。
(6)分组
我们已经知道如何匹配重复的单个字符,如*、?、+,那么如何匹配重复的一组字符呢?我们可以用小括号()来指定一个分组或者叫子表达式,然后再指定重复次数,最后再进行其他操作。如(\d{1,3}.){3}\d{1,3},从左到右看:\d{1,3}匹配1到3位的数字,(\d{1,3}.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})。很显然上面这个表达式会匹配255.255.255.0,相信你似乎已经发现可以用来匹配IP,事实是它也会匹配999.999.999.999这样错误的IP地址。这里我们给出一个正确的IP匹配正则表达式:((2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?),应该不难理解。
(7)反义

符号说明
\W匹配任意不是字母,数字,下划线,汉字的字符
\S匹配任意不是空白符的字符
\D匹配任意非数字的字符
\B匹配不是单词开头或结束的位置
[^x]匹配除了x以外的任意字符
[^aeiou]匹配除了aeiou这几个字母以外的任意字符

限于时间关系,关于正则表达式的内容就介绍到这里。相信大家会在以后的工作学习中能体会到正则表达式的强大之处。
非常感谢这篇文章作者 正则表达式30分钟入门教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值