码迷,mamicode.com
首页 > 其他好文 > 详细

正则表达式

时间:2019-08-03 12:31:51      阅读:90      评论:0      收藏:0      [点我收藏+]

标签:bsp   邮件   相同   index   连续   引用   水平   复杂   指定表   

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的其它字符;
{}:匹配长度,如 \s{3} 表示匹配三个空白字符;
?:它前面相邻的字符重复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]\\d{9}";
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("^\\d{4}$");
Pattern p = Pattern.compile("(\\d{4})([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("\\d{2}");

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。分别指的是什么?

正则表达式

标签:bsp   邮件   相同   index   连续   引用   水平   复杂   指定表   

原文地址:https://www.cnblogs.com/ren549047861/p/11294311.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!