查询数据
一、查询语句的基本语法
通过数据可得查询,用户可以从数据库中获取需要的数据。数据库中可能包含着无数的表,表中可能包含着无数的记录。因此,要获取所需的数据并非易事。MySQL中可以使用select语句来查询数据。根据查询的条件的不同。数据库系统图会找到不同的数据。通过select语句可以很方便的获取所需的信息。
MySQL中,select的基本语法形式如下:
SELECT 属性列表
FROM 表名和视图列表
[WHERE 条件表达式1]
[GROUP BY 属性名1 [HAVING 条件表达式2]]
[ORDER BY 属性名2 [ASC\DESC]]
其中,“属性列表”参数表示需要查询的字段名;“表名和视图列表”参数表示从此处指定的表或者视图中查询数据,表和视图可以有多个。“条件表达式1”参数指定查询查询条件;“属性名1”参数指按该字段中的数据进行分组;“条件表达式2”参数表示满足该表达式的数据才能输出;“属性名2”参数指按该字段中的数据进行排序、排序方式由“ASC”和“DESC”两个参数指出。“ASC”参数表示按升序排序,是默认参数。“DESC”参数表示按降序排序。
如果有WHERE子句,就按照“条件表达式1”指定的条件进行查询,如果没有WHERE子句,就查询所有记录。
如果有GROUP BY子句,就按照“属性名1”指定的字段进行分组,如果GROUP BY子句后带着HAVING关键字,那么只有满足“条件表达式2”中指定的条件的才能够输出,GROUP BY子句通常和COUNT()、SUM()等聚合函数一起使用。
如果有ORDER BY 子句,就按照“属性名2”指定的字段进行程序。排序方式由“ASC”和“DESC”两个参数指出,默认的情况下是“ASC”。
二、在单表上查询数据
查询数据时,可以从一张表中查询数据,也可以从多张表中同时查询数据。两者的查询方式上有一定的区别。因为单表查询只在一张表上进行操作,所以查询比较简单。
1、单表上查询所有的字段
a、列表中所有的字段
查询employee表中的所有字段
e.g SELECT num,d_id,name,age,sex,homeaddr FORM employee;
b、使用“*”查询所有字段
e.g SELECT*FORM employee;
2、查询指定的字段
可以在SELECT语句的“属性列表”中列出所需查询的字段。e.g 下面查询employee表中num、name、sex和homeaddr这四个字段的数据。按顺序排列。
SELECT num,name,sex,homeaddr FROM employee;
3、查询指定记录
用户可以根据自己的需要来设置查询条件,按条件进行查询。查询的结果必须满足查询条件。e.g 用户需要查找d_id为1001的记录,那么可以设置“d_id=1001”这个条件,这样查询的结果中的记录就都会满足这个条件。WHERE子句可以用来指定查询条件。
WHERE 条件表达式
a.g SELECT * FORM employee WHERE d_id=1001;
查询条件
比较 =,<,<=,>,>=,!=,!<,!>,
指定范围 BETWEEN AND,NOT BETWEEN AND
指定集合 IN,NOT IN
匹配字符 LIKE,NOT LIKE
是否为空值 is NULL,is NOT NULL
多个查询条件 AND,OR
4、带IN关键字的查询
IN关键字可以判断某个字段的值是否在指定的集合中。如果字段值在集合中,则满足查询条件,该记录将被查询出来。如果不在集合中,则不满足查询条件。
[NOT] IN (元素1,元素2,...... ,元素n)
e.g SELECT * FROM employee WHERE d_id IN(1001,1004);
SELECT * FROM employee WHERE name NOT IN(‘张三’,‘李四’);
5、带BETWEEN AND的范围查询
可以判读某个字段的值是否在指定的范围内。如果字段的值在指定的范围内,则满足查询条件,该记录被查询出来,如果不在指定范围内,则不满足查询条件。
[NOT] BETWEEN 取值1 AND 取值2
e.g SELECT * FROM employee WHERE age BETWEEN 15 AND 25;
SELECT * FROM employee WHERE age NOT BETWEEN 15 AND 25;
6、带LIKE的字符匹配查询
可以匹配字符串是否相等。
[NOT] LIKE '字符串'
e.g SELECT * FROM employee WHERE name LIKE 'Aric';
SELECT * FROM employee WHERE name='Aric';
SELECT * FROM employee WHERE homeaddr LIKE '北京%'
”%“通配符,表示任意一串字符,模糊查询。不能用”=“。
SELECT * FROM employee WHERE name LIKE 'Ar_c';
"_"通配符,表示任意一个字符。
SELECT * FROM employee WHERE name NOT LIKE '张%'; //查询所有不姓张的
7、查询空值
可以用来判断字段的值是否是空值。
IS [NOT] NULL
其中,”NOT“是可选参数,加上NOT表示字段不是空值时满足条件。
E.g SELECT * FROM work WHERE info IS NULL;
SELECT * FROM work WHERE info IS NOT NULL;
8、带AND的多条件查询
可以用来联合多个条件进行查询。使用AND关键字时,只有同时满足所有查询条件的记录会被查询出来,如果不满足这些查询条件的其中一个,这样的记录将被排除掉。
条件表达式1 AND 条件表达式2 [..... AND 条件表达式n]
其中,AND 可以连接两个条件表达式。而且,可以同时使用多个AND关键字,这样可以连接更多的条件表达式。
e.g SELECT * FROM employee WHERE d_id=1001 AND sex LIKE '男';
SELECT * FROM employee WHERE d_id<1004 AND age<26 AND sex='男';
9、带OR的多条件查询
可以用来联合多个条件进行查询,但是与AND关键字不同。使用OR关键字时,只要满足这几个查询条件的其中一个,这样的记录将会被查询出来。如果不满足这些查询条件中的任何一个,这样的记录将被排除掉。
条件表达式1 OR 条件表达式2 [... OR 条件表达式n]
其中,OR可以用来连接两个条件表达式。而且,可以同时使用多个OR关键字,这样可以连接更多的条件表达式。
e.g SELECT * FROM employee WHERE d_id=1001 OR sex LIKE '男';
SELECT * FROM employee WHERE num IN(1,2,3) OR age BETWEEN 24 AND 25 OR homeaddr LIKE '%北京市%';
SELECT * FROM employee WHERE num IN(1,2,3) AND age=25 OR sex='女';
10、查询结果不重复
如果表中的某些字段上没有唯一性约束,这些字段可能存在着重复的值。
SELECT DISTINCT d_id FROM employee;
11、给查询结果排序
从表中查询出来的数据可能是无序的,或者其排列顺序不是用户所期望的顺序。为了使查询结果的顺序满足用户的要求,可以使用ORDER BY关键字对记录进行排序。
ORDER BY 属性名[ASC/DESC]
SELECT * FROM employee ORDER BY age DESC;
SELECT * FROM employee ORDER BY d_id ASC,age DESC;
多个时,首先使用第一个字段排序,若第一个里面有一样的数值,再用第二个字段排序。
12、分组查询
GROUP BY关键字可以将查询结果按某个字段或者多个字段进行分组。字段中值相等的为一组。
GROUP BY 属性名[HAVING 条件表达式][WITH ROLLUP]
a、单独使用GROUP BY 关键字来分组
e.g SELECT * FROM employee GROUP BY sex;
b、GROUP BY 关键字与GROUP_CONCAT()函数一起使用
e.g SELECT sex, COUNT(sex) FROM employee GROUP BY sex;
sex字段取值相同的为一组,然后对每一组使用集合函数COUNT()进行计算,求出每一组的记录数。
c、GROUP BY 关键字与集合函数一起使用
d、GROUP BY关键字与HAVING一起使用
e.g SELECT sex, COUNT(sex) FROM employee GROUP BY sex HAVING COUNT(sex)>=3;
按employee表的sex字段进行分组查询,然后显示记录数大于等于3的分组。
e、按多个字段进行
e.g SELECT * FROM employee GROUP BY d_id,sex;
按照d_id和sex进行分组。
f、GROUP BY 关键字与WITH ROLLUP一起使用
SELECT sex, COUNT(sex) FROM employee GROUP BY sex WITH ROLLUP;
ROLLUP上面所有记录的总和。
13、用LIMIT限制查询结果的数量
可以用来指定查询结果从哪条记录开始显示,还可以指定一共显示多少条记录。
a、不指定初始位置
e.g SELECT * FROM employee LIMIT 2;
限制只显示其中两条。不指定初始位置。
b、指定初始位置
e.g SELECT * FROM employee LIMIT 0,2;
只显示前两条,指定初始位置。‘0’指第一条位置。
三、使用聚合函数查询数据
集合函数包括COUNT()、SUM()、AVG()、MAX()和MIN()。其中,COUNT()用来查询字段的最大值;AVG()用来计算字段的值的平均值;MAX()用来查询字段的最大值;MIN()用来查询字段的最小值。当需要对表中的记录求和、求平均值、查询最大值、查询最小值等操作时,可以使用集合函数。例如,需要计算学生成绩表中平均成绩,可以使用AVG()函数。GROUP BY关键字通常需要与集合函数一起使用。
1、COUNT()函数
用来统计记录的条数。如果要统计employee表中有多少条记录,可以使用COUNT()函数。如果要统计employee表中不同部门的人数,也可以使用COUNT()函数。
e.g 下面使用COUNT()函数统计employee表中的记录数,
SELECT COUNT(*) FROM employee;
e.g 下面使用COUNT()函数统计employee表中不同d_id值的记录数。
SELECT d_id,COUNT(*) FROM employee GROUP BY d_id;
2、SUM()函数
求和函数。可以求出表中某个字段取值的综合。
e.g 下面使用SUN()函数统计grade表中学号为1001的同学的总成绩。
SELECT num,SUM(score) FROM grade WHERE num=1001;
e.g 下面将grade表按照num字段进行分组,然后,使用SUM()函数统计个分组的总成绩。
SELECT num,SUM(score) FROM grade GROUP BY num;
3、AVG()函数
是求平均值的函数。使用AVG()函数可以求出表达中某个字段取值的平均值。
e.g 下面使用AVG()函数计算employee表中平均年龄(age)。
SELECT AVG(age) FROM employee;
e.g 下面使用AVG()函数计算grade表中不同科目的平均成绩。
SELECT course,AVG(score) FROM grade GROUP BY course;
4、MAX()函数
求最大值。
e.g 下面使用MAX()函数查询grade表中不同科目的最高成绩。
SELECT MAX(age) FROM employee;
e.g 下面使用MAX()函数查询grade表中不同科目的最高成绩
SELECT num,course,MAX(score) FROM grade GROUP BY coures;
e.g 下面使用MAX()函数查询work表中name字段的最大值。
SELECT MAX(name) FROM work;
比较字符串。
5、MIN()函数
求最小值。
e.g 下面使用MIN()函数查询employee表中的最小年龄。
SELECT MIN(age) FROM employee;
e.g 下面使用MIN()函数查询grade表中不同科目的最低成绩。
SELECT course,MIN(score) FROM grade GROUP BY course;
四、多表上连接查询
是将两个或两个以上的表按某个条件连接起来,从中选取需要的数据。连接查询是同时查询两个或者两个以上的表时使用的。当不同的表中存在表示相同意义的字段时,可以通过该字段来连接这几个表。例如,学生表中有段来表示课程号。那么,可以通过学生表中的course_id字段与课程表中的num字段来进行连接查询。连接查询包括内连接查询和外连接查询。
1、内连接查询
可以查询两个或者两个以上的表。当两个表中存在表示相同意义的字段时,可以通过该字段来连接这两个表。当该字段的值相等时,就查询出该记录。
e.g 下面使用内连接查询的方式查询employee表和department表,在执行内连接查询之前,先分别查看employee表和department表中的记录,以便进行比较。
SELECT num,name,employee.d_id,age,d_name,function FROM employee,department WHERE employee.d_id=department.d_id;
2、外连接查询
可以查询两个或者两个以上的表。外连接查询也需要通过制定字段来进行连接。当该字段取值相等时,可以查询出该记录。而且,该字段取值不相等的记录也可以查询出来。外连接查询包括左连接查询和右连接查询。
SELECT 属性名列表
FROM 表名1 LEFT/RIGHT JOIN 表名2
ON 表名1.属性名=表名2.属性名2;
a、左连接查询
e.g 下面使用左链接查询的方式查询employee表和department,两表通过d_id字段进行连接。
SELECT num,name,employee.d_id,age,sex,d_name,function FROM employee LEFT JOIN department ON employee.d_id=department.d_id;
b、右连接查询
e.g 下面使用右链接查询的方式查询employee表和department,两表通过d_id字段进行连接。
SELECT num,name,employee.d_id,age,sex,d_name,function FROM employee RIGHT JOIN department ON employee.d_id=department.d_id;
3、符合条件连接查询
在连接查询时,也可以增加其他的限制条件。通过多个条件的符合查询,可以使查询结果更加准确。例如,employee表和department表进行连接查询时,可以限制age字段的取值必须大于24.这样,可以更加准确的查询出年龄大于24岁的员工的信息。
e.g 下面使用employee表中的age字段的值必须大于24。
SELECT num,name,employee.d_id,age,sex,d_name,function FROM employee,department WHERE employee.d_id=department.d_id AND age>24;
e.g 下面使用内连接查询的方式查询employee表和department表。并以age字段的升序方式显示查询结果。
SELECT num,name,employee.d_id,age,sex,d_name,function FROM employee,department WHERE employee.d_id=department.d_id GROUP BY age ASC;
五、子查询
是将一个查询语句嵌套在另一个查询语句中。内层查询语句的查询结果,可以为外层查询语句提供查询条件。因为在特定情况下,一个查询语句的条件需要另一个查询语句来获取。例如,现在需要从学生成绩表中查询计算机系学生的各科成绩。那么,首先就必须知道哪些课程是计算机系学生选修的。因此,必须先查询计算机系学生选修的课程,然后根据这些课程来查询计算机系学生的各科成绩。通过子查询,可以实现多表之前的查询。子查询中可能包括IN、NOT IN、ANY、ALL、EXISTS、NOT EXISTS等关键字。子查询中还可能包含比较运算符,如=、!=、>、<等。
1、带IN关键字的子查询
一个查询语句的条件可能落在另一个SELECT语句的查询结果中。这可以通过IN关键字来判断。例如,要查询哪些同学选择了计算机系开设的课程。先必须从课程表中查询出计算机系开设了哪些课程。然后再从学生表中进行查询。如果学生选修的课程在前面查询出来的课程中,则查询出该同学的信息。这可以用带IN关键字的子查询来实现。
e.g 下面查询employee表中的记录,这些记录的d_id字段必须在department表中出现过。
SELECT * FROM employee WHERE d_id IN (SELECT d_id FROM department);
e.g 下面查询employee表中的记录,这些记录的d_id字段必须没有在department表中出现过。
SELECT * FROM employee WHERE d_id NOT IN (SELECT d_id FROM department);
2、带比较运算符的子查询
这些比较运算符包括=、!=、>、<、<=、>=、<>等。其中,<>与!=是等价的。在子查询时使用的非常广泛。
e.g 下面从employee_stu表中查询获得一等奖学金的学生的学号、姓名和分数,各个等级的奖学金的最低分存储在scholarship表中。
SELECT id,name,score FROM computer_stu WHERE score>=(SELECT score FROM scholarship WHERE level=1);
e.g 下面在department表中查询那些部门没有年龄为24岁的员工,员工的年龄存储在employee表中。先查询一下employee表和department表,以便进行对比。
SELECT d_id,d_name FROM department WHERE d_id!=(SELECT d_id FROM employee WHERE age=24);
SELECT d_id,d_name FROM department WHERE d_id<>(SELECT d_id FROM employee WHERE age=24);
3、带EXISTS关键字的子查询
表示存在。使用此关键字时,内层查询语句不返回查询的记录。而是返回一个真假值。如果内层查询语句查询到满足条件的记录,就返回一个真值(true)。否则,将返回一个假值(false)。当返回的值是真值时,外层查询语句将进行查询。当返回值是假值时,外层查询语句不进行查询或者查询不出任何记录。
e.g 下面如果department表中存在d_id取值为1003的记录,则查询employee表的记录。
SELECT * FROM employee WHERE EXISTS (SELECT d_name FROM department WHERE d_id=1003);
e.g 下面如果department表中存在d_id取值为1003的记录,则查询employee表中age大于24的记录。
SELECT * FROM employee WHERE age>24 AND EXISTS (SELECT d_name FROM department WHERE d_id=1003);
e.g 下面如果department表中不存在d_id取值为1003的记录,则查询employee表的记录。
SELECT * FROM employee WHERE NOT EXISTS (SELECT d_name FROM department WHERE d_id=1003);
4、带ANY关键字的子查询
表示满足其中任一条件。使用ANY关键字时,只要满足内层查询语句返回的结果中的任何一个,就可以通过该条件来执行外层查询语句。例如,需要查询哪些同学能够获得奖学金。那么,首先必须从奖学金表中查询出各种奖学金要求的最低分。只要一个同学的成绩高于不同奖学金最低返的任何一个,这个同学就可以获得奖学金。通常与比较运算符一起使用。
e.g 下面从computer_stu表中查询出哪些同学可以获得奖学金,奖学金的信息存储在scholarship表中。先查看一下computer_stu表和scholarship表。
SELECT * FROM computer_stu WHERE score>=ANY (SELECT score FROM scholarship);
5、带ALL关键字的子查询
满足所有条件。只有满足内层查询语句返回的所有结果,才可以执行外层查询语句。例如,需要查询哪些同学能够获得一等奖学金。首先必须从奖学金表中查询出各种奖学金要求的最低分。因为一等奖学金的分数最高。只有当同学的成绩高于所有奖学金最低分时。这个同学才能获得一等奖学金。
e.g 下面从computer_stu表中查询出哪些同学可以获得一等奖学金。奖学金的信息存储在scholarship表中,先需要从scholarship表中查询出各种奖学金的最低分,然后,从computer_stu表中查询哪些人的分数高于所有奖学金的最低分。
SELECT * FROM computer_stu WHERE score>=ALL(SELECT score FROM scholarship);
六、合并查询结果
是将多个SELECT语句的查询结果合并到一起。某种情况下,需要将几个SELECT语句查询出来的结果合并起来显示。例如,现在需要查询公司甲和公司乙这两个公司所有员工的信息。这就需要从公司甲中查询出所有员工的信息,再从公司乙中查询出所有员工的信息,然后将这两次的查询结果合并到一起。进行合并操作使用UNION和UNION ALL关键字,
使用UNION关键字时,数据库系统会将所有的查询结果合并到一起,然后去除掉相同的记录,而UNION ALL关键字则只是简单的合并到一起。
SELECT语句1
UNION/UNION ALL
SELECT语句2
UNION/UNION ALL .....
SELECT语句n
UNION/UNION ALL
e.g 下面从department表和employee表中查询d_id字段的取值。然后通过UNION关键字将结果合并到一起。首先,先看看department表和employee表中d_id字段的取值。
SELECT d_id FROM department UNION SELECT d_id FROM employee;
SELECT d_id FROM department UNION ALL SELECT d_id FROM employee;
八、使用正则表达式查询
正则表达式是用某种模式去匹配一类字符串的一个方式。例如,使用正则表达式可以查询出包含A\B\C其中任一字母的字符串。正则表达式的查询能力比通配字符的查询能力更强大,而且更加灵活。正则表达式可以应用于非常复杂查询。
MySQL中,使用REGEXP关键字来匹配查询正则表达式。
属性名 REGEXP ’匹配方式’
正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。
列目录时, dir *.txt或ls *.txt中的*.txt就不是一个正则表达式,因为这里*与正则式的*的含义是不同的。
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
3.1 普通字符
由所有那些未显式指定为元字符的打印和非打印字符组成。这包括所有的大写和小写字母字符,所有数字,所有标点符号以及一些符号。
3.2 非打印字符
字符 | 含义 |
---|---|
\cx | 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。 |
\f | 匹配一个换页符。等价于 \x0c 和 \cL。 |
\n | 匹配一个换行符。等价于 \x0a 和 \cJ。 |
\r | 匹配一个回车符。等价于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
\t | 匹配一个制表符。等价于 \x09 和 \cI。 |
\v | 匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
3.3 特殊字符
所谓特殊字符,就是一些有特殊含义的字符,如上面说的”*.txt”中的*,简单的说就是表示任何字符串的意思。如果要查找文件名中有*的文件,则需要对*进行转义,即在其前加一个\。ls \*.txt。正则表达式有以下特殊字符。
特别字符 | 说明 |
---|---|
$ | 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身,请使用 \$。 |
( ) | 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。 |
* | 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。 |
+ | 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。 |
. | 匹配除换行符 \n之外的任何单字符。要匹配 .,请使用 \。 |
[ | 标记一个中括号表达式的开始。要匹配 [,请使用 \[。 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。 |
\ | 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n’ 匹配字符 ‘n’。’\n’ 匹配换行符。序列 ‘\\’ 匹配 “\”,而 ‘\(’ 则匹配 “(”。 |
^ | 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^。 |
{ | 标记限定符表达式的开始。要匹配 {,请使用 \{。 |
| | 指明两项之间的一个选择。要匹配 |,请使用 \|。 |
构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与操作符将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。
3.4 限定符
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有*或+或?或{n}或{n,}或{n,m}共6种。
*、+和?限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个?就可以实现非贪婪或最小匹配。
正则表达式的限定符有:
字符 | 描述 |
---|---|
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,’zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。例如,”do(es)?” 可以匹配 “do” 或 “does” 中的”do” 。? 等价于 {0,1}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,’o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,’o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。’o{1,}’ 等价于 ‘o+’。’o{0,}’ 则等价于 ‘o*’。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,”o{1,3}” 将匹配 “fooooood” 中的前三个 o。’o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。 |
3.5 定位符
用来描述字符串或单词的边界,^和$分别指字符串的开始与结束,\b描述单词的前或后边界,\B表示非单词边界。不能对定位符使用限定符。
3.6 选择
用圆括号将所有选择项括起来,相邻的选择项之间用|分隔。但用圆括号会有一个副作用,是相关的匹配会被缓存,此时可用?:放在第一个选项前来消除这种副作用。
其中?:是非捕获元之一,还有两个非捕获元是?=和?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。
3.7 后向引用
对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到的内容存储。存储子匹配的缓冲区编号从 1 开始,连续编号直至最大 99 个子表达式。每个缓冲区都可以使用 ‘\n’ 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。
可以使用非捕获元字符 ‘?:’, ‘?=’, or ‘?!’ 来忽略对相关匹配的保存。
相同优先级的从左到右进行运算,不同优先级的运算先高后低。各种操作符的优先级从高到低如下:
操作符 | 描述 |
---|---|
\ | 转义符 |
(), (?:), (?=), [] | 圆括号和方括号 |
*, +, ?, {n}, {n,}, {n,m} | 限定符 |
^, $, \anymetacharacter | 位置和顺序 |
| | “或”操作 |
字符 | 描述 |
---|---|
\ | 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,’n’ 匹配字符 “n”。’\n’ 匹配一个换行符。序列 ‘\\’ 匹配 “\” 而 “\(” 则匹配 “(”。 |
^ | 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。 |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,’zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。例如,”do(es)?” 可以匹配 “do” 或 “does” 中的”do” 。? 等价于 {0,1}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,’o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,’o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。’o{1,}’ 等价于 ‘o+’。’o{0,}’ 则等价于 ‘o*’。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,”o{1,3}” 将匹配 “fooooood” 中的前三个 o。’o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。 |
? | 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,’o+?’ 将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’。 |
. | 匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用象 ‘[.\n]’ 的模式。 |
(pattern) | 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 ‘\(’ 或 ‘\)’。 |
(?:pattern) | 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。例如, ‘industr(?:y|ies) 就是一个比 ‘industry|industries’ 更简略的表达式。 |
(?=pattern) | 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,’Windows (?=95|98|NT|2000)’ 能匹配 “Windows 2000″ 中的 “Windows” ,但不能匹配 “Windows 3.1″ 中的 “Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?!pattern) | 负向预查,在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如’Windows (?!95|98|NT|2000)’ 能匹配 “Windows 3.1″ 中的 “Windows”,但不能匹配 “Windows 2000″ 中的 “Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 |
x|y | 匹配 x 或 y。例如,’z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 则匹配 “zood” 或 “food”。 |
[xyz] | 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。 |
[^xyz] | 负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p'。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,’[a-z]’ 可以匹配 ‘a’ 到 ‘z’ 范围内的任意小写字母字符。 |
[^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,’[^a-z]’ 可以匹配任何不在 ‘a’ 到 ‘z’ 范围内的任意字符。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。 |
\B | 匹配非单词边界。’er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。 |
\cx | 匹配由 x 指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。 |
\d | 匹配一个数字字符。等价于 [0-9]。 |
\D | 匹配一个非数字字符。等价于 [^0-9]。 |
\f | 匹配一个换页符。等价于 \x0c 和 \cL。 |
\n | 匹配一个换行符。等价于 \x0a 和 \cJ。 |
\r | 匹配一个回车符。等价于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
\t | 匹配一个制表符。等价于 \x09 和 \cI。 |
\v | 匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
\w | 匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’。 |
\W | 匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]’。 |
\xn | 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,’\x41′ 匹配 “A”。’\x041′ 则等价于 ‘\x04′ & “1″。正则表达式中可以使用 ASCII 编码。. |
\num | 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,’(.)\1′ 匹配两个连续的相同字符。 |
\n | 标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。 |
\nm | 标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。 |
\nml | 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。 |
\un | 匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (?)。 |
正则表达式 | 说明 |
---|---|
/\b([a-z]+) \1\b/gi | 一个单词连续出现的位置 |
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/ | 将一个URL解析为协议、域、端口及相对路径 |
/^(?:Chapter|Section) [1-9][0-9]{0,1}$/ | 定位章节的位置 |
/[-a-z]/ | A至z共26个字母再加一个-号。 |
/ter\b/ | 可匹配chapter,而不能terminal |
/\Bapt/ | 可匹配chapter,而不能aptitude |
/Windows(?=95 |98 |NT )/ | 可匹配Windows95或Windows98或WindowsNT,当找到一个匹配后,从Windows后面开始进行下一次 |
一切从最基本的开始。模式,是正规表达式最基本的元素,它们是一组描述字符串特征的字符。模式可以很简单,由普通的字符串组成,也可以非常复杂,往往用特殊的字符表示一个范围内的字符、重复出现,或表示上下文。例如:
^once
这个模式包含一个特殊的字符^,表示该模式只匹配那些以once开头的字符串。例如该模式与字符串”once upon a time”匹配,与”There once was a man from NewYork”不匹配。正如如^符号表示开头一样,$符号用来匹配那些以给定模式结尾的字符串。
bucket$
这个模式与”Who kept all of this cash in a bucket”匹配,与”buckets”不匹配。字符^和$同时使用时,表示精确匹配(字符串与模式一样)。例如:
^bucket$
只匹配字符串”bucket”。如果一个模式不包括^和$,那么它与任何包含该模式的字符串匹配。例如:模式
once
与字符串
There once was a man from NewYork
Who kept all of his cash in a bucket.
是匹配的。
在该模式中的字母(o-n-c-e)是字面的字符,也就是说,他们表示该字母本身,数字也是一样的。其他一些稍微复杂的字符,如标点符号和白字符(空格、制表符等),要用到转义序列。所有的转义序列都用反斜杠(\)打头。制表符的转义序列是:\t。所以如果我们要检测一个字符串是否以制表符开头,可以用这个模式:
^\t
类似的,用\n表示“新行”,\r表示回车。其他的特殊符号,可以用在前面加上反斜杠,如反斜杠本身用\\表示,句号.用\.表示,以此类推。
7.2 字符簇
在INTERNET的程序中,正规表达式通常用来验证用户的输入。当用户提交一个FORM以后,要判断输入的电话号码、地址、EMAIL地址、信用卡号码等是否有效,用普通的基于字面的字符是不够的。
所以要用一种更自由的描述我们要的模式的办法,它就是字符簇。要建立一个表示所有元音字符的字符簇,就把所有的元音字符放在一个方括号里:
[AaEeIiOoUu]
这个模式与任何元音字符匹配,但只能表示一个字符。用连字号可以表示一个字符的范围,如:
[a-z] //匹配所有的小写字母
[A-Z] //匹配所有的大写字母
[a-zA-Z] //匹配所有的字母
[0-9] //匹配所有的数字
[0-9\.\-] //匹配所有的数字,句号和减号
[ \f\r\t\n] //匹配所有的白字符
同样的,这些也只表示一个字符,这是一个非常重要的。如果要匹配一个由一个小写字母和一位数字组成的字符串,比如”z2″、”t6″或”g7″,但不是”ab2″、”r2d3″ 或”b52″的话,用这个模式:
^[a-z][0-9]$
尽管[a-z]代表26个字母的范围,但在这里它只能与第一个字符是小写字母的字符串匹配。
前面曾经提到^表示字符串的开头,但它还有另外一个含义。当在一组方括号里使用^是,它表示“非”或“排除”的意思,常常用来剔除某个字符。还用前面的例子,我们要求第一个字符不能是数字:
^[^0-9][0-9]$
这个模式与”&5″、”g7″及”-2″是匹配的,但与”12″、”66″是不匹配的。下面是几个排除特定字符的例子:
[^a-z] //除了小写字母以外的所有字符
[^\\\/\^] //除了(\)(/)(^)之外的所有字符
[^\”\’] //除了双引号(”)和单引号(’)之外的所有字符
特殊字符”.” (点,句号)在正规表达式中用来表示除了“新行”之外的所有字符。所以模式”^.5$”与任何两个字符的、以数字5结尾和以其他非“新行”字符开头的字符串匹配。模式”.”可以匹配任何字符串,除了空串和只包括一个“新行”的字符串。
PHP的正规表达式有一些内置的通用字符簇,列表如下:
字符簇含义
[[:alpha:]] 任何字母
[[:digit:]] 任何数字
[[:alnum:]] 任何字母和数字
[[:space:]] 任何白字符
[[:upper:]] 任何大写字母
[[:lower:]] 任何小写字母
[[:punct:]] 任何标点符号
[[:xdigit:]] 任何16进制的数字,相当于[0-9a-fA-F]
7.3 确定重复出现
到现在为止,你已经知道如何去匹配一个字母或数字,但更多的情况下,可能要匹配一个单词或一组数字。一个单词有若干个字母组成,一组数字有若干个单数组成。跟在字符或字符簇后面的花括号({})用来确定前面的内容的重复出现的次数。
字符簇 含义
^[a-zA-Z_]$ 所有的字母和下划线
^[[:alpha:]]{3}$ 所有的3个字母的单词
^a$ 字母a
^a{4}$ aaaa
^a{2,4}$ aa,aaa或aaaa
^a{1,3}$ a,aa或aaa
^a{2,}$ 包含多于两个a的字符串
^a{2,} 如:aardvark和aaab,但apple不行
a{2,} 如:baad和aaa,但Nantucket不行
\t{2} 两个制表符
.{2} 所有的两个字符
这些例子描述了花括号的三种不同的用法。一个数字,{x}的意思是“前面的字符或字符簇只出现x次”;一个数字加逗号,{x,}的意思是“前面的内容出现x或更多的次数”;两个用逗号分隔的数字,{x,y}表示“前面的内容至少出现x次,但不超过y次”。我们可以把模式扩展到更多的单词或数字:
^[a-zA-Z0-9_]{1,}$ //所有包含一个以上的字母、数字或下划线的字符串
^[0-9]{1,}$ //所有的正数
^\-{0,1}[0-9]{1,}$ //所有的整数
^\-{0,1}[0-9]{0,}\.{0,1}[0-9]{0,}$ //所有的小数
最后一个例子不太好理解,是吗?这么看吧:与所有以一个可选的负号(\-{0,1})开头(^)、跟着0个或更多的数字([0-9]{0,})、和一个可选的小数点(\.{0,1})再跟上0个或多个数字([0-9]{0,}),并且没有其他任何东西($)。下面你将知道能够使用的更为简单的方法。
特殊字符”?”与{0,1}是相等的,它们都代表着:“0个或1个前面的内容”或“前面的内容是可选的”。所以刚才的例子可以简化为:
^\-?[0-9]{0,}\.?[0-9]{0,}$
特殊字符”*”与{0,}是相等的,它们都代表着“0个或多个前面的内容”。最后,字符”+”与 {1,}是相等的,表示“1个或多个前面的内容”,所以上面的4个例子可以写成:
^[a-zA-Z0-9_]+$ //所有包含一个以上的字母、数字或下划线的字符串
^[0-9]+$ //所有的正数
^\-?[0-9]+$ //所有的整数
^\-?[0-9]*\.?[0-9]*$ //所有的小数
当然这并不能从技术上降低正规表达式的复杂性,但可以使它们更容易阅读。
正则表达式非常有用,查找、匹配、处理字符串、替换和转换字符串,输入输出等。而且各种语言都支持,例如.NET正则库,JDK正则包, Perl, JavaScript等各种脚本语言都支持正则表达式。下面整理一些常用的正则表达式。
字符 |
描述 |
\ | 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。 |
^ | 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。 |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。 |
? | 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo",'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'。 |
. | 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。 |
(pattern) | 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 '\(' 或 '\)'。 |
(?:pattern) | 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。 |
(?=pattern) | 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?!pattern) | 负向预查,在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 |
x|y | 匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。 |
[xyz] | 字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。 |
[^xyz] | 负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。 |
[^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 |
\B | 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 |
\cx | 匹配由 x 指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。 |
\d | 匹配一个数字字符。等价于 [0-9]。 |
\D | 匹配一个非数字字符。等价于 [^0-9]。 |
\f | 匹配一个换页符。等价于 \x0c 和 \cL。 |
\n | 匹配一个换行符。等价于 \x0a 和 \cJ。 |
\r | 匹配一个回车符。等价于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
\S |
匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
\t | 匹配一个制表符。等价于 \x09 和 \cI。 |
\v | 匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
\w | 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。 |
\W | 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。 |
\xn | 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,'\x41' 匹配 "A"。'\x041' 则等价于 '\x04' & "1"。正则表达式中可以使用 ASCII 编码。 |
\num | 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)\1' 匹配两个连续的相同字符。 |
\n | 标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。 |
\nm | 标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。 |
\nml | 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。 |
/i | 使正则表达式对大小写不敏感, (?-i)是关闭大小写不敏感 (?i)te(?-i)st应该匹配TEst,但是不能匹配teST或TEST. |
/s | 开启“单行模式”,即点号“.”匹配新行符 |
/m | 开启“多行模式”,即“^”和“$”匹配新行符的前面和后面的位置。 |
^[0-9]*$ | 只能输入数字 |
^\d{n}$ | 只能输入n位的数字 |
^\d{n,}$ | 只能输入至少n位的数字 |
^\d{m,n}$ | 只能输入m~n位的数字 |
^(0|[1-9][0-9]*)$ | 只能输入零和非零开头的数字 |
^[0-9]+(.[0-9]{2})?$ | 只能输入有两位小数的正实数 |
^[0-9]+(.[0-9]{1,3})?$ | 只能输入有1~3位小数的正实数 |
^\+?[1-9][0-9]*$ | 只能输入非零的正整数 |
^\-[1-9][]0-9"*$ | 只能输入非零的负整数 |
^.{3}$ | 只能输入长度为3的字符 |
^[A-Za-z]+$ | 只能输入由26个英文字母组成的字符串 |
^[A-Za-z0-9]+$ | 只能输入由数字和26个英文字母组成的字符串 |
^\w+$ | 只能输入由数字、26个英文字母或者下划线组成的字符串 |
^[a-zA-Z]\w{5,17}$ | 验证用户密码:以字母开头,长度在6~18之间,只能包含字符、数字和下划线。 |
[^%&',;=?$\x22]+ | 验证是否含有^%&',;=?$\"等字符 |
^[\u4e00-\u9fa5]{0,}$ | 只能输入汉字 |
^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$ | 验证Email地址 |
^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$ | 验证InternetURL |
^\d{15}|\d{18}$ | 验证身份证号(15位或18位数字) |
^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$ | 验证IP地址 |
(\w)\1 | 匹配两个两个重叠出现的字符 例如,"aabbc11asd", 返回结果为aa bb 11三组match |
<(?<tag>[^\s>]+)[^>]*>.*</\k<tag>> | 匹配成对的HTML标签 |
(?!) | 不出现,负声明 下例演示如何取得一个<a>标签对中的全部内容,即使其中包含别的HTML tag。 string newsContent = @"url:<a href=""1.html""><img src=""1.gif"">test<span style=""color:red;""> Regex</span></a>."; Regex regEnd = new Regex(@"<\s*a[^>]*>([^<]|<(?!/a))*<\s*/a\s*>",RegexOptions.Multiline); |
1. 匹配组
常用的组匹配:(实用)
(
exp)
匹配exp并且捕获到一个自动命名的组
(?<
name>
exp)
匹配exp并且捕获到组’name’ (?=
exp)
exp出现在声明右侧,但exp不作为匹配
括号中的模式必须出现在声明右侧,但不作为匹配的一部分 ,例如:
输入: public keywod string "abc";
正则:\b\w+(?=ing\b),返回“str”,
意思为:匹配以ing结束的单词,但ing不作为返回(?<=
exp)
exp出现在声明左侧,但exp不作为匹配
括号中的模式必须出现在声明左侧,但不作为匹配的一部分 ,例如:
输入: public remember string "abc";
正则:(?<=\bre)\w+\b,返回“member”,
意思为:匹配以re开头的单词,但re不作为返回
(?!
exp)
exp不出现在声明右侧,但exp不作为匹配
括号中的模式必须不出现在声明右侧 ,例如:
输入: remember aqa bqu "abc";
正则:\b\w*q(?!u)\w*\b,返回“aqa”,
意思为:匹配带q后面不是跟随u的单词
(?<!
exp)
exp不出现在声明左侧,但exp不作为匹配
输入:public string keywod = "abc"; string value = "test";
目的:匹配 关键字="",例如获得关