正则表达式概述
在编程中,处理字符串是一项常见且重要的任务。而正则表达式,作为一种强大的字符串匹配工具,能帮助我们高效地完成各种复杂的字符串处理需求。无论是数据验证、文本搜索与替换,还是日志分析等场景,正则表达式都能大显身手。今天,我们就来全面了解一下正则表达式。
一、什么是正则表达式
正则表达式,又称正规表示法、常规表示法(英语:Regular Expression,在代码中常简写为 regex、regexp 或 RE),是计算机科学中的一个概念。它使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。
正则表达式就像 JSON 一样,是一种通用的标准,被多种开发语言所支持,包括 Java、JavaScript、C、C++、C#、Python、SQL 等。在 Javaweb 项目中,正则表达式通常用于前端验证,所以我们接下来将以 JavaScript 为例来学习正则表达式。
二、正则表达式的创建方式
在 JavaScript 中,有两种创建正则表达式的方式:
- 第一种方式:使用
RegExp
构造函数
var reg = new RegExp('^a$');
- 第二种方式:使用字面量形式,这种方式在 JavaScript 中更推荐使用
var reg = /^a$/;
三、第一个正则表达式示例
为了让大家更直观地理解正则表达式的使用,我们来看一个简单的例子。这个例子实现的功能是:验证输入的文本是否为字符 “a”。
<html lang="en">
<head><meta charset="UTF-8"><title>正则表达式</title>
</head>
<body>
<input type="text" id="name" />
<span id="msg"></span>
<br><br>
<input type="button" onclick="test()" value="测试">
</body>
<script type="text/javascript">function test(){var value = document.getElementById("name").value;// 定义一个匹配字符a的正则表达式var reg = new RegExp('^a$'); // 第一种方式// var reg = /^a$/; // 第二种方式 在js中推荐使用// 获取正则匹配的结果 true falsevar result = reg.test(value);// 定义显示结果var html = result ? '合法' : '不合法';// 在页面显示正则匹配结果document.getElementById("msg").innerHTML = html;}
</script>
</html>
在这个例子中,当我们在输入框中输入内容并点击 “测试” 按钮时,JavaScript 函数test()
会获取输入框的值,然后使用正则表达式^a$
来匹配该值。如果匹配成功(即输入的是 “a”),则显示 “合法”;否则,显示 “不合法”。其中,^
表示匹配输入字符串的开始位置,$
表示匹配输入字符串的结束位置,所以^a$
只能匹配单独的字符 “a”。
四、正则表达式的匹配规则
1. 字符类匹配
[abc]
:匹配 a、b 或 c 中的任意一个字符。[^abc]
:匹配除了 a、b、c 之外的任何单个字符。[a-zA-Z]
:匹配 a 到 z 或 A 到 Z 中的任意一个字母,包括两头的字母。[0-9]
:匹配 0 到 9 之间的任意一个数字。
2. 元字符匹配
.
:匹配除换行符(\n、\r)之外的任何单个字符。如果要匹配包括\n
在内的任何字符,可以使用像(.|\n)
这样的模式。\w
:匹配字母、数字、下划线,等价于[A-Za-z0-9_]
。\W
:匹配非字母、数字、下划线,等价于[^A-Za-z0-9_]
。\s
:匹配任何空白字符,包括空格、制表符、换页符等等,等价于[ \f\n\r\t\v]
。\S
:匹配任何非空白字符,等价于[^ \f\n\r\t\v]
。\d
:匹配一个数字字符,等价于[0-9]
。\D
:匹配一个非数字字符,等价于[^0-9]
。\b
:匹配一个单词边界,也就是指单词和空格间的位置。例如,'er\b'
可以匹配 “never” 中的'er'
,但不能匹配 “verb” 中的'er'
。^
:匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^
也匹配'\n'
或'\r'
之后的位置。$
:匹配输入字符串的结束位置。如果设置了 RegExp 对象的 Multiline 属性,$
也匹配'\n'
或'\r'
之前的位置。
3. 数量词
X?
:表示 X 出现一次或一次也没有。X*
:表示 X 出现零次或多次。X+
:表示 X 出现一次或多次。X{n}
:表示 X 恰好出现 n 次。X{n,}
:表示 X 至少出现 n 次。X{n,m}
:表示 X 至少出现 n 次,但是不超过 m 次。
4. 字符转义
如果你想查找元字符本身,比如查找.
或者*
,就需要使用\
来取消这些字符的特殊意义。例如,要匹配www.txjava.cn
,正则表达式应该是www\.txjava\.cn
;要匹配c:\windows
,正则表达式应该是c:\\windows
。当然,要查找\
本身,也得用\\
。
5. 分组
如果想要重复一个字符串,可以用小括号来指定子表达式(也叫做分组),然后就可以指定这个子表达式的重复次数了。
例如,(\d{1,3}\.){3}\d{1,3}
是一个简单的 IP 地址匹配表达式。我们来分析一下:\d{1,3}
匹配 1 到 3 位的数字,(\d{1,3}\.){3}
匹配三位数字加上一个英文句号(这个整体作为分组)重复 3 次,最后再加上一个 1 到 3 位的数字(\d{1,3})
。不过,这个表达式也会匹配像 256.300.888.999 这种不可能存在的 IP 地址(因为 IP 地址中每个数字都不能大于 255)。
一个能正确匹配 IP 地址的正则表达式相对复杂,IPv4 的 ip 地址都是(1~225).(0~255).(0~255).(1~255)的格式,对应的正则表达式如下:
^(1\d{2}|2[0-4]\d|22[0-5]|[1-9]\d|[1-9])\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])$
五、常见的正则表达式
1. 数字校验
- 数字:
^[0-9]*$
- n 位的数字:
^\d{n}$
- 至少 n 位的数字:
^\d{n,}$
- m-n 位的数字:
^\d{m,n}$
- 零和非零开头的数字:
^(0|[1-9][0-9]*)$
- 非零开头的最多带两位小数的数字:
^([1-9][0-9]*)+(.[0-9]{1,2})?$
- 带 1-2 位小数的正数或负数:
^(\-)?\d+(\.\d{1,2})?$
- 正数、负数、和小数:
^(\-|\+)?\d+(\.\d+)?$
- 有两位小数的正实数:
^[0-9]+(.[0-9]{2})?$
- 有 1~3 位小数的正实数:
^[0-9]+(.[0-9]{1,3})?$
- 非零的正整数:
^[1-9]\d*$
或^([1-9][0-9]*){1,3}$
或^\+?[1-9][0-9]*$
- 非零的负整数:
^\-[1-9][0-9] *$
或^-[1-9]\d*$
- 非负整数:
^\d+$
或^[1-9]\d*|0$
- 非正整数:
^-[1-9]\d*|0$
或^((-\d+)|(0+))$
- 非负浮点数:
^\d+(\.\d+)?$
或^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
- 非正浮点数:
^((-\d+(\.\d+)?)|(0+(\.0+)?))$
或^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
- 正浮点数:
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$
- 负浮点数:
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$
- 浮点数:
^(-?\d+)(\.\d+)?$
或^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
2. 字符校验
- 汉字:
^[\u4e00-\u9fa5]{0,}$
- 英文和数字:
^[A-Za-z0-9]+$
或^[A-Za-z0-9]{4,40}$
- 长度为 3-20 的所有字符:
^.{3,20}$
- 由 26 个英文字母组成的字符串:
^[A-Za-z]+$
- 由 26 个大写英文字母组成的字符串:
^[A-Z]+$
- 由 26 个小写英文字母组成的字符串:
^[a-z]+$
- 由数字和 26 个英文字母组成的字符串:
^[A-Za-z0-9]+$
- 由数字、26 个英文字母或者下划线组成的字符串:
^\w+$
或^\w{3,20}$
- 中文、英文、数字包括下划线:
^[\u4E00-\u9FA5A-Za-z0-9_]+$
- 中文、英文、数字但不包括下划线等符号:
^[\u4E00-\u9FA5A-Za-z0-9]+$
- 可以输入含有
^%&',;=?$\"
等字符:[^%&',;=?$\x22]+
- 禁止输入含有
~“”
的字符:[^~\x22]+
3. 特殊需求校验
- Email 地址:
^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
- InternetURL:
^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
- 手机号码:
^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
- 国内电话号码(如 0511-4405222、021-87888822):
\d{3}-\d{8}|\d{4}-\d{7}
- 身份证号(15 位、18 位数字):
^\d{15}|\d{18}$
- 短身份证号码(数字、字母 x 结尾):
^([0-9]){7,18}(x|X)?$
或^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
- 帐号是否合法(字母开头,允许 5-16 字节,允许字母数字下划线):
^[a-zA-Z][a-zA-Z0-9_]{4,15}$
- 密码(以字母开头,长度在 6~18 之间,只能包含字母、数字和下划线):
^[a-zA-Z]\w{5,17}$
- 日期格式:
^\d{4}-\d{1,2}-\d{1,2}
- 一年的 12 个月(01~09 和 1~12):
^(0?[1-9]|1[0-2])$
- 一个月的 31 天(01~09 和 1~31):
^((0?[1-9])|((1|2)[0-9])|30|31)$
六、总结
正则表达式是一种非常强大的工具,掌握它能让我们在处理字符串时事半功倍。本文介绍了正则表达式的基本概念、创建方式、匹配规则以及一些常见的正则表达式示例。当然,正则表达式的内容远不止这些,还有很多高级特性和复杂用法需要我们在实际应用中不断学习和探索。