Java正则表达式

反斜杠\的处理

如果你在其它语言中使用过正则表达式,那你立刻就能发现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——————————————————

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值