标签:bsp 邮件 相同 index 连续 引用 水平 复杂 指定表
正则表达式是用来操作字符串的,即用一些特定的符号来表示一些代码操作,从而简化对字符串的复杂操作。换句话说,用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征。
\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:单词边界。匹配的是一个位置而不是字符,这个位置的一侧是构成单词的字符,另一侧是非单词字符、字符串的开始或结束位置。
^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"匹配,所以输出以上结果。
单行,多行模式,都是正则表达式的模式修饰符里面出现的参数。
单行跟多行是冲突的,一次只能指定一个选项,不能同时使用
1.什么是正则表达式的贪婪与非贪婪匹配
如:String str="abcaxc";
Patter p="ab*c";
贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc(ab*c)。
非贪婪匹配:就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(ab*c)。
2.编程中如何区分两种模式
默认是贪婪模式;在量词后面直接加上一个问号?就是非贪婪模式。
量词:{m,n}:m到n个
*:任意多个
+:一个到多个
?:0或一个
\d:数字[0-9];
\D:非数字[^0-9];
(1)捕获组捕获到的内容,不仅可以在正则表达式外部通过程序进行引用,也可以在正则表达式内部进行引用,这种引用方式就是反向引用。要了解反向引用,首先要了解捕获组,关于捕获组,请参考相关资料。
(2)捕获组(Expression)在匹配成功时,会将子表达式匹配到的内容,保存到内存中一个以数字编号的组里,可以简单的认为是对一个局部变量进行了赋值,这时就可以通过反向引用方式,引用这个局部变量的值。一个捕获组(Expression)在匹配成功之前,它的内容可以是不确定的,一旦匹配成功,它的内容就确定了,反向引用的内容也就是确定的了。
(3)反向引用必然要与捕获组一同使用的,如果没有捕获组,而使用了反向引用的语法,不同语言的处理方式不一致,有的语言会抛异常,有的语言会当作普通的转义处理。
(4)示例说明:
源字符串:abcdebbcde
正则表达式:([ab])\1,这里的”\1”就是反向引用。
对于正则表达式“([ab])\1”,捕获组中的子表达式“[ab]”虽然可以匹配“a”或者“b”,但是捕获组一旦匹配成功,反向引用的内容也就确定了。如果捕获组匹配到“a”,那么反向引用也就只能匹配“a”,同理,如果捕获组匹配到的是“b”,那么反向引用也就只能匹配“b”。由于后面反向引用“\1”的限制,要求必须是两个相同的字符,在这里也就是“aa”或者“bb”才能匹配成功。
预搜索是用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像 \b ^ $ \< \> 这样的锚定作用,仅仅用于指定一个位置,不参与内容匹配。
还是来用例子说话吧:
(1)正则表达式:(?<=src=\").*?(?=\"), \"表示转义,即双引号"
其中(?<=)为反向预搜索,表示要匹配的字符串前面必须是src="
(?=)为正向预搜索,表示要匹配的字符串后面必须是"
.*?表示要匹配的内容
(2)用上例来匹配以下文本:
待测试的文本:<img src="/UploadFiles/image/20140304/20140304094318_2971.png" />
那么执行这个正则表达式后,就可以提取出/UploadFiles/image/20140304/20140304094318_2971.png
(3)预搜索的语法:
(?=xxx)
正向预搜索(向右)
正向预搜索,判断当前位置右侧是否能匹配指定表达式
(?!xxx)
正向预搜索否定,判断当前位置右侧是否不能够匹配指定表达式
(?<=xxx)
反向预搜索(向左)
反向预搜索,判断当前位置左侧是否能够匹配指定表达式
(?<!xxx)
反向预搜索否定,判断当前位置左侧是否不能够匹配指定表达式
预搜索分两种,一种是向右,另外一种是向左。
根据对电子邮箱格式要求的不同所得的正则表达式也是不同的。下例写得有点复杂,仅做参考:
/^[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}为{起始字数,结束字数} 。
验证手机号码:13XXXX,15XXXX,18XXX开头的手机号码:
String tel="13900098900";
String telReg="1[358]\\d{9}";
System.out.println(tel.matches(telReg));
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+"));
}
}
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!
标签:bsp 邮件 相同 index 连续 引用 水平 复杂 指定表
原文地址:https://www.cnblogs.com/ren549047861/p/11294311.html