反斜杠\的处理
如果你在其它语言中使用过正则表达式,那你立刻就能发现java的反斜杠\的不同处理。在其它语言中,\表示“我想要在正则表达式中插入一个普通的反斜杠,请不要给他任何特殊的意义。”而在java的正则表达式中,\的意思是“我要插入一个正则表达式的反斜杠,所以其后的字符具有特殊的意义。”例如,在java中你想表示一位数字,那么正则表达式应该是\d。如果你想在正则表达式中插入一个普通的反斜杠,则应该这样\\。不过换行和制表符之类的东西只需要使用单反斜杠线:\n\t。
例:
String ss = "\\h";
System.out.println(ss.matches("\\\\h"));
输出:true
字符类
. 任意字符,不包括换行符
[abc] a或b或c,表示特定限制条件,里面不分排序
\s 空白符(空格、tab、换行、换页和回车)
\S 非空白符
\d 数字[0-9]
\D 非数字
\w 词字符[a-z A-Z 0-9]
\W 非词字符
^ 一行的起始
$ 一行的结束
\b 词的边界
\B 非词的边界
\G 前一个匹配的结束
量词
贪婪型:尽可能多的匹配
? 0个或1个
* 0个或多个
+ 一个或多个
(? * + 在正则表达式中有特殊的意义,如果要当成普通字符使用,必须使用\将其转义)
{n} 刚好n次
{n,} 至少n次
{n,m} 至少n次,但不超过m次
例:
“ {2,}”表示2个以上的空格
“^ +”表示以一个或多个空格开头
懒惰型:匹配满足模式所需的最少字符数,用?来指定
例:
String s = "abcd";
Pattern p = Pattern.compile(".+");
Matcher m = p.matcher(s);
while(m.find()){
System.out.println(m.group());
}
输出:
abcd
String s = "abcd";
Pattern p = Pattern.compile(".+?");
Matcher m = p.matcher(s);
while(m.find()){
System.out.println(m.group());
}
输出:
a
b
c
d
CharSequence
接口CharSequence从CharBuffer、String、StringBuffer、StringBuilder类之中抽象出了字符序列的一般化定义,因此,这些类都实现了该接口。
Pattern和Matcher
用Pattern.compile()方法编译正则表达式,生成Pattern对象;将想要检索的字符串传入Pattern对象的Matcher()方法,生成Matcher对象,它有很多功能可用。
1、Matcher.matches()
public boolean matches()判断整个输入字符串是否匹配正则表达式模式
例:
Pattern p = Pattern.compile("((\\S+)\\s+)");
Matcher m = p.matcher("a ");
System.out.println(m.matches());
输出:true
Pattern p = Pattern.compile("((\\S+)\\s+)");
Matcher m = p.matcher("a b");
System.out.println(m.matches());
输出:false
在Pattern中提供了static方法:
public static boolean matches(String regex, CharSequence input)
作用同Matcher里的matches()方法。
2、Matcher.lookingAt()
public boolean lookingAt()用于判断字符串的始部分是否能够匹配模式。
例:
Pattern p = Pattern.compile("((\\S+)\\s+)");
Matcher m = p.matcher("a b");
System.out.println(m.matches());
输出:true
3、Matcher.find()和Matcher.group()
public boolean find()用来在字符串中查找多个匹配,像迭代器那样前向遍历输入字符串。
public String group()返回前一次匹配操作的值,只返回已匹配的部分。
例:
Pattern p = Pattern.compile("\\S+\\s+");
Matcher m = p.matcher("a b ");
while(m.find()){
System.out.println(m.group());
}
输出:
a
b
find还有一个带参数的方法:
public boolean find(int start) 参数表示字符串中字符的位置,并以其作为搜索的起点。此方法能根据其参数的值,不断重新设定搜索的起始位置。
4、组(Groups)
组是用括号划分的正则表达式,可以根据组的编号来引用某个组。组号为0表示整个表达式,组号1表示被第一对括号括起的组,依次类推。因此,在下面这个表达式,
A(B(C))D
中有三个组:组0是ABCD,组1是BC,组2是C。
Matcher对象提供了一系列方法,用以获取与组相关的信息:
Public int groupCount()返回该匹配器的模式中分组数目,第0组不包括在内。
Public String group()返回在前一次匹配操作(例如find(),lookingAt(),matchers(),这3个方法都会移动内部的匹配指针)的第0组(整个匹配)。
Public String group(int i) 指定组号,没有这个组会抛异常。
Public int start()返回在这一次匹配操作中寻找到的组的起始索引;
Public int end()返回在这一次匹配操作中寻找到的组的最后一个字符索引加1的值。
组的方法没有匹配会抛异常,所以一般是和find一起使用。
例:
Pattern p = Pattern.compile("\\S+\\s+");
Matcher m = p.matcher("a b ");
while(m.find()){
System.out.println(m.group());
System.out.println(m.start());
System.out.println(m.end());
}
输出:
a
0
2
b
2
4
5、Pattern标记
Pattern类的compile()方法还有另一个版本,它接受一个标记参数,以调整匹配的行为:
public static Pattern compile(String regex, int flags)
常用的标记模式有
Pattern.CASE_INSENSITIVE(?i):不考虑大小写
例:
Pattern p = Pattern.compile("aB");
Matcher m = p.matcher("ab");
System.out.println(m.matches());
输出:false
Pattern p = Pattern.compile("aB", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("ab");
System.out.println(m.matches());
输出true
Pattern.COMMENTS(?x):忽略空格,以#开始直到行末的注释也会被忽略。
例:
Pattern p = Pattern.compile("a b", Pattern.COMMENTS);
Matcher m = p.matcher("ab");
System.out.println(m.matches());
输出:true
Pattern p = Pattern.compile("a b");
Matcher m = p.matcher("ab");
System.out.println(m.matches());
输出:false
Pattern.MULTILINE(?m):在多行模式下,表达式^和$分别匹配一行的开始和结束。默认情况下,这些表达式仅匹配输入的完整字符串的开始和结束。
例:
Pattern p = Pattern.compile("(\\S+\\s+\\S+)$");
Matcher m = p.matcher("where there is a will\n" +"there is a way");
while(m.find()){
System.out.println(m.group());
}
输出:a way
Pattern p = Pattern.compile("(\\S+\\s+\\S+)$", Pattern.MULTILINE);
Matcher m = p.matcher("where there is a will\n" +"there is a way");
while(m.find()){
System.out.println(m.group());
}
输出:
a will
a way
Pattern.DOTALL(?s):此模式中,表达式“.”匹配所有字符,包括行终结符\n。默认情况下“.”表达式不匹配行终结符。
例:
Pattern p = Pattern.compile("/\\*!(.+)!\\*/", Pattern.DOTALL);
Matcher m = p.matcher("/*!where there is a will\n" +"there is a way!*/");
System.out.println(m.matches());
输出:true
Pattern p = Pattern.compile("/\\*!(.+)!\\*/");
Matcher m = p.matcher("/*!where there is a will\n" +"there is a way!*/");
System.out.println(m.matches());
输出:false
可以直接在正则表达式中使用标记,只需要将上述括起来的字符插入正则表达式中,如
Pattern.compile("(\\S+\\s+\\S+)$", Pattern.MULTILINE)
等价于
Pattern.compile("(?m)(\\S+\\s+\\S+)$");
可以通过(|)操作符组合多个标记的功能:
Pattern p = Pattern.compile("^java", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("java is a language\n" +"Java is easy to learn");
while(m.find()){
System.out.println(m.group());
}
输出:
java
Java
6、Split()
String s = “aa!!bb!!cc!!dd”;
String ss[] = Pattern.compile(“!!”).split(s, 2);
同
String s = “aa!!bb!!cc!!dd”;
String ss[] = s.split(“!!”, 2);
等价
Split的第二个参数表示限制将输入分割成字符串的数量。
7、替换操作
replaceFirst(String s)替换第一个匹配成功的部分
replaceAll(String s)替换所有匹配成功的部分
(这两个方法在String对象中也有,所以一般使用String对象里的就可以了,开销小一些)
appendReplacement(StringBuffer buff, String s)执行渐进式的替换,该方法允许你在执行替换的过程中,操作用来替换的字符串。
例:
String s = "asdfijk";
Pattern p = Pattern.compile("[aeiou]");
Matcher m = p.matcher(s);
StringBuffer b = new StringBuffer();
while(m.find()){
m.appendReplacement(b, m.group().toUpperCase());
System.out.println(b.toString());
}
输出:
A
AsdfI
appendTail(StringBuffer buff)在执行了一次或多次appendReplacement()之后,调用此方法可以将输入字符串余下的部分复制到buff中。
例:
String s = "asdfijk";
Pattern p = Pattern.compile("[aeiou]");
Matcher m = p.matcher(s);
StringBuffer b = new StringBuffer();
while(m.find()){
m.appendReplacement(b, m.group().toUpperCase());
System.out.println(b.toString());
}
m.appendTail(b);
System.out.println(b.toString());
输出:
A
AsdfI
AsdfIjk
8、reset() 方法
通过reset()方法,可以将现有的Matcher对象应用于一个新的字符序列,
例:
Pattern p = Pattern.compile("[frb][aiu][gx]");
Matcher m = p.matcher("fix the rug with bags");
while(m.find()){
System.out.print(m.group()+" ");
}
System.out.println();
m.reset("fix the rig with bags");
while(m.find()){
System.out.print(m.group()+" ");
}
输出:
fix rug bag
fix rig bag
使用不带参数的reset()方法,可以将Matcher对象重新设置到当前字符序列的起始位置。
9、Scanner定界符
在默认情况下,Scanner根据空白字符对输入进行分词,
例:
Scanner s = new Scanner("12, 45, 23, 89,32");
while(s.hasNext()){
System.out.println(s.next());
}
输出:
12,
45,
23,
89,32
但是你可以用正则表达式指定自己所需的定界符。我们可以用useDelimiter来设置定界符,同时,还有一个delimiter()方法,用来返回当前正在作为定界符使用的Pattern对象。
例:
Scanner s = new Scanner("12, 45, 23, 89,32");
s.useDelimiter("\\s*,\\s*");//逗号包括逗号前后任意的空白字符
while(s.hasNext()){
System.out.println(s.next());
}
输出:
12
45
23
89
32
应用
1、验证是否为邮箱地址
String s = "abcd@qq.com";
Pattern p = Pattern.compile("[\\w-\\.]+@([\\w-]+\\.)+[\\w-]+");
System.out.println(p.matcher(s).matches());
输出:true
注: . 具有特殊意义,所以要用\将其转义为普通字符。
2、去除html标记
String s = "<a href=/\"index.html/\">主页</a>";
Pattern p = Pattern.compile("<.+?>");
Matcher m = p.matcher(s);
String r = m.replaceAll("");
System.out.println(r);
输出:
主页
注:正则表达式中的?代表懒惰匹配,如果去掉?,则s全部被替换了。
————————————————-end——————————————————