最后更新日:2014年11月08日
[0-9A-Za-z]匹配数字、大写字母或小写字母
[\\x00-\\x7F]所有ASCII中的字符
[0\\-9]匹配0、-或者9三个字符中的一个
[1\\]3]匹配1、]或者3三个字符中的一个
[^-12]匹配除-、1或者2三个字符中的任意一个
[1^2]匹配1、^或者2三个字符中的一个
[-09]在首位将元字符转为普通字符可以不加\\-
转义字符,依然是匹配0、-或者9三个字符中的一个
[012]34]可匹配034]、134]、234]
\\[123]匹配[123],这是包含了[]的情形
[^0-9][0-9]匹配2个字符,第一个字符不能包含0-9,第二个必须包含0-9,^表示排除当前可能
\\d等价于[0-9],而\\D取的是其补集
\\w等价于[0-9A-Za-z],‘_’下划线是包含进来的,而\\W取的是其补集
\\s等价于[ \t\r\n\v\f]等一系列空,而\\S取的是其补集
[^\\d]匹配出0-9之外的所有字符
[\\d\\D]或者[\\s\\S]或者[\\w\\W]匹配所有字符
匹配一切实数: [-+]?(([1-9]+|[0]\\.[\\d]+)|([1-9]+|[0]))
匹配整数: [-+]?([1-9]+|[0])
另:0的中括号可省略
(?s)^.单行
模式匹配所有字符
[[a-z]&&[^aeiou]]匹配除a、e、i、o、u外的所有21个英文字母
\\d{6}匹配六位数的数字,形式是:{m,n}表示至少出现m次,至多出现n次
*等价于{0,} +等价于{1,} ?等价于{0,1}
pio{2,3}k表示o至少出现2次,至多出现3次
Pio?k表示o至多出现1次
\"[^\"]*\"匹配包括双引号及其间的内容,0个或者多个,且不包括引号
\".*\"匹配包括双引号间的所有内容
.可以匹配任何字符,但是不包括\n换行符
类似<head>这种open tag的匹配:<[[^/]&&[^>]]+>
类似</html>这种close tag的匹配:</[[^/]&&[^>]]+>
类似<br />这种self-closing tag的匹配:<[[^<]&&[^>]]+/>
<[\\d\\D]+>匹配所有<内容>标签
//.*匹配
注释//后的所有内容,//是单行注释
/*[\d\D]*?*/匹配/**/间的所有内容,/**/是多行注释
匹配优先量词忽略优先量词**?++????{m,n}{m,n}?{m,}{m,}?{,n}{,n}?
最大区别在于:如果有段文字包括<tr></tr><tr></tr><tr></tr>,那么如果要匹配<tr></tr>,匹配优先量词将匹配所有<tr></tr>,即匹配出<tr></tr><tr></tr><tr></tr>;而忽略优先量词只会匹配出来一个<tr></tr>
\\*\\?匹配*?(这是忽略优先量词)
\\{4,5}匹配字符串{4,5}
([1-9]+\\.[\\d]+|[0]\\.\\d+)匹配小数,前面也说过,[]可以省略不写,一样的
\\d{2}[3]匹配一个3位数,前两位各位数字范围为0-9,第三位必须为数字3;如果写成(\\d{2}[3])?表示这个匹配的三位数作为整体可以出现0次或者1次,括号的这种功能叫做分组
注意:如在一个
表达式,如[0-9A-Za-z]首和尾分别加上^和$,即^[0-9A-Za-z]$表示定位整个字符串,如果要提取数据,应去掉^和$,^和$也可分别用\\A和\\Z代替。^表示开始,$表示结束
ab+匹配第一个为a,第二个b至少出现一次
(ab)+匹配ab作为一个整体至少出现一次
(\\d{1}|\\d{2})匹配1位数或者2位数的数字,这也是()的另一个功能,多选结构,|表示或者
<a\s+href\s*=\s*[“’]?([^”’\s]+)[“’]?>([^<]+)</a>匹配<a href=”url”>text</a>,提取url和text的内容用group(1)和group(2)
([a-z])9\\1匹配p9p之类的,\\1代替了([a-z]),称反向引用匹配
又如:"a1a2c3c".matches("([a-z])1\\12([a-z])3\\2")
非捕获分组:(?:\\d{4})——即,在开括号后面加上“?:”,既使层次清晰又提高分组效率
例:
class="java">
String s = "2011-12-23";
Pattern regex = Pattern.compile("(?:\\d{4})-(\\d{2})-(\\d{2})");
Matcher matcher = regex.matcher(s);
if(matcher.matches()){
//由于有非捕获分组的存在,group(1)原本应为2011,现为12
System.out.println(matcher.group(1));//12
}else{
System.out.println("错误!");
}
对于要匹配左括号(“(”)、右括号(“)”)和或(“|”)这类特殊字符,必须进行转义,即前加\\
\\b\\w+\\b匹配文中的所有
单词,\\b能匹配的\\B就不能,反之亦然
单词边界:形式一:\\b内容\\b 形式二:内容\\b 形式三:\\b内容
肯定顺序环视:(?=内容),从右判断
否定顺序环视:(?!内容),从右判断
肯定逆序环视:(?<=内容),从左判断
否定逆序环视:(?<!内容),从左判断
(?=w)[a-z]+匹配在a-z组成的字母串中,第一个字母必须是w
(?!(dog|cat))[a-z]+匹配在a-z组成的字母串中,前三个字母不能是dog或者cat
<(?<!/)a>匹配<a>
前面提到,匹配不是元音字母的
正则可以写为:[[a-z]&&[^aeiou]],
现在用环视可以写为:(?![aeiou])[a-z]
环视结构中也可以用引用分组,且不影响引用分组
JAVA中环视匹配的文本长度可以无限长,但是这个无限长必须有个明确上限量
(\\b\\w+\\b)\\s+\\1匹配重复单词,如hello hello,最好写成(\\b\\w+\\b)\\s+\\b\\1\\b
注意体会以下两条
正则表达式:
boolean one = Pattern.compile("((?i)abc)\\1").matcher("aBcaBc").matches();//true
boolean two = Pattern.compile("(?i)(abc)\\1").matcher("aBcAbC").matches();//true
注意:
((?i)abc)\\1前后须一致
(?i)(abc)\\1前后不须一致,只要是abc这三个字母就可以了
注意体会以下两条正则表达式:
//没有消除元字符的含义,*表示0个或多个
boolean one = Pattern.compile("ca*t").matcher("caaaaaaaaaat").matches();
//消除了元字符的含义,*就是表示*,\\Q和\\E之间的是消除元字符含义的内容
boolean two = Pattern.compile("\\Qca*t\\E").matcher("ca*t").matches();
[我们]匹配\u6211或者我,因为“\u6211”就是“我”
[\u4e00-\u9fff]匹配中文字符
正则表达式的理论模型:有穷自动机。有穷自动机必须满足四个条件:1、具有有限多个状态2、有一套状态转换函数(“规则”)3、有一个开始状态4、有一个或多个最终状态
一些有点难
理解的简单解释:
String字符串正则匹配写法\n -> 回车\\n\\n -> \n\\\\n\\\n -> \\n\\\\\\n\\s -> \s\\\\s\\\\ -> \\\\\\\\\\\\\" -> \"\\\\\"
//如何验证
//step1:想一个要验证的,如\"
//step2:输出\",如String s = "\\\"";System.out.println(s);//结果就是\"
//step3:正则匹配则要转义:\\\" -> \\\\\"
Pattern pattern = Pattern.compile("\\\\\"");
System.out.println(pattern.matcher("\\\"").matches());
System.out.println("\\\"");//\"
具体的JAVA代码示例
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
public class Test {
public static void main(String[] args) {
//示例1
//写法一
String s = "sfs411111sdf453535345ffgdgf";
Pattern regex = Pattern.compile("[1-9]+");
//String s = "sdasdasd<table>sdjhjks</table>sadasd3fsdf";
//Pattern regex = Pattern.compile("<table[\\s]*[\\s\\S]*?>[\\s\\S]+?</table>");
Matcher matcher = regex.matcher(s);
System.out.println(matcher.matches());
while(matcher.find()){
System.out.println(matcher.group());
}
//写法二(更推荐)
Pattern pattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
Matcher matcher = pattern.matcher("2134-32-12 3213-23-12");
while(matcher.find()){
System.out.println(matcher.group());
}
//示例2
String s = "2011-12-23";
Pattern regex = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
Matcher matcher = regex.matcher(s);
System.out.println(matcher.matches());
//分组编号取决于开括号"("的顺序
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
System.out.println(matcher.group(3));
//示例3
//把字母替换成中文“我”
String s = "a1c4er3";
Pattern regex = Pattern.compile("[a-z]");
System.out.println(regex.matcher(s).replaceAll("我"));
//把-替换成年月日和哈哈
String s = "2012-12-21";
Pattern regex = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
System.out.println(regex.matcher(s).replaceAll("$1年$2月$3日"));
System.out.println(regex.matcher(s).replaceAll("哈哈"));
//给小数前加上$符号,记住"\\$$0"这种写法,\\$转义成$,$0匹配整个字符串
String s = "12.45";
Pattern regex = Pattern.compile("\\d+.\\d+");
System.out.println(regex.matcher(s).matches());
System.out.println(regex.matcher(s).replaceAll("\\$$0"));
//加上单引号
String s = Pattern.compile("\\b([a-z])\\b").matcher ("a,b,c").replaceAll("'$1'");
System.out.println(s);
//示例4
boolean b = Pattern.compile("正则表达式").matcher("匹配字符串").matches();
boolean b = Pattern.matches("正则表达式","匹配字符串");
System.out.println(b);
//示例5(虽然写起来方便,但不推荐)
String s = "匹配字符串";
System.out.println(s.matches("正则"));
//合并一句为:
boolean b = "1232".matches("\\d{4}");
System.out.println(b);
//示例6(不区分大小写模式)
boolean b = Pattern.compile("the",Pattern.CASE_INSENSITIVE).matcher("THe").matches();
//或者写成(推荐这么写)
boolean b = Pattern.compile("(?i)the").matcher("THe").matches();
boolean b = Pattern.compile("t(?i)he").matcher("tHE").matches();
boolean b = Pattern.compile("t(?i:h)e").matcher("tHe").matches();
boolean b = Pattern.compile("t((?i)h)e").matcher("tHe").matches();
System.out.println(b);
//示例7(单行模式)
//注:多行是Pattern.MULTILINE和(?m)
//在单行模式下,点号可以匹配任何字符,自然也包括换行符
boolean b = Pattern.compile(".*",Pattern.DOTALL).matcher("a").matches();
//或者写成(推荐这么写)
boolean b = Pattern.compile("(?s).*").matcher("abc").matches();
System.out.println(b);
//示例8(注释模式)
boolean b = Pattern.compile("\\d{3} #三位数字",Pattern.COMMENTS).matcher("123").matches();
System.out.println(b);
//示例9(失效修饰符(?-i),使前面起作用的对后面的失效)
boolean b = Pattern.compile("(?i)(foo|zee)(?-i)bar").matcher("ZeEbar").matches();
System.out.println(b);
//示例10(在字符串中能否找到所匹配的字串)
boolean b = Pattern.compile("\\d").matcher("asdjkah4ksd").find();
System.out.println(b);
//示例11(分割)
String s = "2012-12-21";
Pattern pattern = Pattern.compile("-");
//pattern.split(s,2)即分割成两部分:2012和12-21
for(String p :pattern.split(s)){
System.out.println(p);
}
//示例12(分组)
//regex 要匹配的正则表达式(依据正则表达式的括号来分组)
Pattern pattern = Pattern.compile(regex);
Matcher matchr = pattern.matcher(str);
if(matchr.matches()){
int count = matchr.groupCount();
String array[] = new String[count];
if(count==0){
return null;
}else{
for (int i = 0; i < count; i++) {
array[i] = matchr.group(i+1);//分组下标从1开始
}
return array;
}
}else{
return null;
}
}
}