正则表达式
Posted ren549047861
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正则表达式相关的知识,希望对你有一定的参考价值。
1.正则表达式是用来做什么的?用自己的话描述。
正则表达式是用来操作字符串的,即用一些特定的符号来表示一些代码操作,从而简化对字符串的复杂操作。换句话说,用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征。
2.说出下面规则的含义:
\d,\w,\s,.,[1234],[^a-f],,?,+,*,\b
\d : 数字:[0-9];
\w: 单词字符:[a-zA-Z_0-9];
\s: 空白字符:[ \t\n\x0B\f\r];空格、水平制表符、换行、垂直制表符、换页、回车等。
.:任何字符。
[1234]:字符串长度为1,值为1、2、3、4中的一个数字;
[^a-f] :字符串长度为1,值为除了a-f的其它字符;
:匹配长度,如 \s3 表示匹配三个空白字符;
?:它前面相邻的字符重复0或1次;
+:它前面相邻的字符重复1到多次;
*:它前面相邻的字符重复0到多次;
\b:单词边界。匹配的是一个位置而不是字符,这个位置的一侧是构成单词的字符,另一侧是非单词字符、字符串的开始或结束位置。
3.分别说出在单行模式和多行模式下,他们的含义:
^ab, ab$;
先介绍一下多行模式和单行模式的概念:
多行模式:
^ 可以匹配字符串开头(字符串的开始位置),也可以匹配行的开头(即换行符\n之后的位置)
$ 可以匹配字符串结尾(字符串的结束位置), 也可以匹配行的结尾(即换行符\n之前的位置)
单行模式:
^ 只能匹配字符串开头
$ 只能匹配字符串结尾
注意这里有一个知识点:\r为回车符,\n 为换行符。在windows中,我们平常说的换行,实质上是先回车,后换行。
还是来看例子吧,以本题中的^ab , ab$为例:
String str="ab\nab\nab\n";
String reg="^ab";//默认是单行模式;
//String reg=”(?m)^ab”; 这个是多行模式,需要加(?m),m是”multiLine”的缩写。
Pattern p=Pattern.compile(reg);
Matcher m=p.matcher(str);
while(m.find())
System.out.println(m.group());
System.out.println(m.start()+""+m.end());
单行模式时:无输出,也就是没有匹配的字符串。因为单行模式时从头到尾地匹配,字符串"ab\nab\nab\n"和正则表达式"^ab"是不匹配的。
多行模式时:
ab
0 2
ab
3 5
ab
6 8
因为多行模式是从字符串开始匹配到换行符(\n)之前,接下来从\n之后重新匹配再到下一个\n之前(或字符串结束)。字符串"ab\nab\nab\n"中有3个”\n”,每两个”\n”之间的字符都与正则表达式"^ab"匹配,所以输出以上结果。
单行,多行模式,都是正则表达式的模式修饰符里面出现的参数。
单行跟多行是冲突的,一次只能指定一个选项,不能同时使用
4.贪婪模式和非贪婪模式的区别是? 并说出如何使用贪婪模式、如何使用非贪婪模式。
1.什么是正则表达式的贪婪与非贪婪匹配
如:String str="abcaxc";
Patter p="ab*c";
贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc(ab*c)。
非贪婪匹配:就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(ab*c)。
2.编程中如何区分两种模式
默认是贪婪模式;在量词后面直接加上一个问号?就是非贪婪模式。
量词:m,n:m到n个
*:任意多个
+:一个到多个
?:0或一个
5.\D,\d分别表示什么意思?
\d:数字[0-9];
\D:非数字[^0-9];
6.说明反向引用是什么意思?
(1)捕获组捕获到的内容,不仅可以在正则表达式外部通过程序进行引用,也可以在正则表达式内部进行引用,这种引用方式就是反向引用。要了解反向引用,首先要了解捕获组,关于捕获组,请参考相关资料。
(2)捕获组(Expression)在匹配成功时,会将子表达式匹配到的内容,保存到内存中一个以数字编号的组里,可以简单的认为是对一个局部变量进行了赋值,这时就可以通过反向引用方式,引用这个局部变量的值。一个捕获组(Expression)在匹配成功之前,它的内容可以是不确定的,一旦匹配成功,它的内容就确定了,反向引用的内容也就是确定的了。
(3)反向引用必然要与捕获组一同使用的,如果没有捕获组,而使用了反向引用的语法,不同语言的处理方式不一致,有的语言会抛异常,有的语言会当作普通的转义处理。
(4)示例说明:
源字符串:abcdebbcde
正则表达式:([ab])\1,这里的”\1”就是反向引用。
对于正则表达式“([ab])\1”,捕获组中的子表达式“[ab]”虽然可以匹配“a”或者“b”,但是捕获组一旦匹配成功,反向引用的内容也就确定了。如果捕获组匹配到“a”,那么反向引用也就只能匹配“a”,同理,如果捕获组匹配到的是“b”,那么反向引用也就只能匹配“b”。由于后面反向引用“\1”的限制,要求必须是两个相同的字符,在这里也就是“aa”或者“bb”才能匹配成功。
7.说明预搜索的含义?用自己的语言描述。
预搜索是用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像 \b ^ $ \< \> 这样的锚定作用,仅仅用于指定一个位置,不参与内容匹配。
还是来用例子说话吧:
(1)正则表达式:(?<=src=\").*?(?=\"), \"表示转义,即双引号"
其中(?<=)为反向预搜索,表示要匹配的字符串前面必须是src="
(?=)为正向预搜索,表示要匹配的字符串后面必须是"
.*?表示要匹配的内容
(2)用上例来匹配以下文本:
待测试的文本:<img src="/UploadFiles/image/20140304/20140304094318_2971.png" />
那么执行这个正则表达式后,就可以提取出/UploadFiles/image/20140304/20140304094318_2971.png
(3)预搜索的语法:
(?=xxx)
正向预搜索(向右)
正向预搜索,判断当前位置右侧是否能匹配指定表达式
(?!xxx)
正向预搜索否定,判断当前位置右侧是否不能够匹配指定表达式
(?<=xxx)
反向预搜索(向左)
反向预搜索,判断当前位置左侧是否能够匹配指定表达式
(?<!xxx)
反向预搜索否定,判断当前位置左侧是否不能够匹配指定表达式
预搜索分两种,一种是向右,另外一种是向左。
8.【上机】完成电子邮件的表达式
根据对电子邮箱格式要求的不同所得的正则表达式也是不同的。下例写得有点复杂,仅做参考:
/^[a-z]([a-z0-9]*[-_]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[\.][a-z]2,3([\.][a-z]2)?$/i
解释:
①
/内容/i: 构成一个不区分大小写的正则表达式;^ 匹配开始;$ 匹配结束。
②[a-z]: E-Mail前缀必需是一个英文字母开头
③([a-z0-9]*[-_]?[a-z0-9]+)* :和_a_2、aaa11、_1_a_2匹配,和a1_、aaff_33a_、a__aa不匹配,如果是空字符,也是匹配的,*表示0个或者多个。
④*表示0个或多个前面的字符.
⑤[a-z0-9]* :匹配0个或多个英文字母或者数字;[-_]? 匹配0个或1“-”,因为“-”不能连续出现。
⑥[a-z0-9]+: 匹配1个或多个英文字母或者数字,因为“-”不能做为结尾
⑦@: 必需有个有@
⑧([a-z0-9]*[-_]?[a-z0-9]+)+ :见上面([a-z0-9]*[-_]?[a-z0-9]+)*解释,但是不能为空,+表示一个或者为多个。
⑨[\.]: 将特殊字符(.)当成普通字符;[a-z]2,3 匹配2个至3个英文字母,一般为com或者net等。
⑩([\.][a-z]2)? :匹配0个或者1个[\.][a-z]2(比如.cn等) 我不确定一般.com.cn最后部份是不是都是两位的,如果不是请修改2为起始字数,结束字数 。
9.【上机】完成电话号码和手机号码的表达式。
验证手机号码:13XXXX,15XXXX,18XXX开头的手机号码:
String tel="13900098900";
String telReg="1[358]\\d9";
System.out.println(tel.matches(telReg));
10.【上机】完成获取一个html元素的表达式。
11.【上机】完成163网页中所有的图片url地址的表达式。
12.【上机】完成如下测试代码:
package test;
import Java.util.ArrayList;
import Java.util.List;
import Java.util.regex.Matcher;
import Java.util.regex.Pattern;
public class TestRegex
public static void main(String[] args)
// Pattern p = Pattern.compile("^\\d4$");
Pattern p = Pattern.compile("(\\d4)([a-z]2)");
Matcher m = p.matcher("sdfsdfsdf2342423safksd1345flsdf");
// System.out.println(m.matches()); //匹配整个目标字符串
// System.out.println(m.find()); //查找子字符串
List<String> list = new ArrayList<String>();
while(m.find())
System.out.println(m.group()); //group(),group(0)作用是一样的!
// System.out.println(m.group(0));
System.out.println(m.group(1));
System.out.println(m.group(2));
// list.add(m.group());
String[] str = "aa33bb45cc".split("\\d2");
String str2 = "a3sdf4sdf".replaceAll("\\ds", "**");
System.out.println(str2);
System.out.println("asdfsdf".matches("\\w+"));
13.说出:group(),group(1),group(2)的区别。
group(int index)的参数和所匹配正则表达式的分组有关。Index就是正则表达式中组的编号(第几组)。group()和group(0)都是指的整个串,group(1) 指的是第一组的内容,group(2)指的第二组的内容。
代码示例:
String str = "Hello,World! in Java.";
Pattern pattern = Pattern.compile("W(or)(ld!)");//对正则表达式进行分组
Matcher matcher = pattern.matcher(str);
while(matcher.find())
System.out.println("Group 0:"+matcher.group(0));//得到第0组——整个匹配
System.out.println("Group 1:"+matcher.group(1));//得到第一组匹配——与(or)匹配的
System.out.println("Group 2:"+matcher.group(2));//得到第二组匹配——与(ld!)匹配的,组也就是子表达式
结果:
Group 0:World!
Group 1:or
Group 2:ld!
14.【上机】javascript中,正则对象的test方法如何使用?写出测试代码。
15.【上机】Javascript中,字符串的match、split、replace方法,如何使用?写出代码。
16.【上机】Javascript中,使用正则对象时,模式:i,g。分别指的是什么?
以上是关于正则表达式的主要内容,如果未能解决你的问题,请参考以下文章