摘要

很多博客都以 “知道这些正则表达式你可以少些XX行代码” 作为标题,但是总是记不住正则的全部语法,也不太能够白板写一个正则匹配,所以整理了一份基础用法。

image.png

正则表达式语法

字符 说明
\ 将下一个字符标记为特殊字符、文本、反向引用或八进制转义符。例如\n。
^ 表示下面一个字符是开始的位置。如果设置了Multiline属性,^会表示与\n\r之后的位置匹配。(也就是每行开头匹配)。
$ 表示匹配行尾,其他特性同^。
* *闭包。
+ +闭包。
? 表示前面的字符出现1次或0次,相当于{0,1} 。
{n} n必须为非负数,匹配前面的字符至少出现{n}次。例如, o{2} 可以匹配booo,但不能找到bob中的o
{n,} n必须非负,至少匹配n次。但是与{n}不同的地方在于,o{2}可能匹配多次foooooooo,但是o{2,}只匹配一次oooooooo,相当于o+。
{n,m} M和n是非负数,其中n<=m,至少匹配n次,最多m次。
? 这是另外一个?符号,跟在限定符 *,+,?,{n},{n,},{n,m}之后,表示仅匹配所有可能中最短的字符串。 例如, oooo 使用 o?,只匹配单个o。
. 匹配\r\n以外的所有单个字符。
(pattern) 匹配pattern并捕获该匹配的子表达式。可以使用$0…$9属性从结果匹配集合中检索捕获的匹配。
(?:pattern) 匹配pattern,但不捕获子表达式。
(?!pattern) 执行反向预测先行搜索的子表达式(就是匹配不符合pattern模式的字符串),不捕获字串。
x|y 匹配x或y。|
[xyz] 字符集,匹配包含的任一字符。
[^xyz] 反向字符集,匹配未包含的任何字符。
[a-z] 字符范围,按照ascII的顺序捕获其中的任意字符
\b 匹配字符边界,即匹配一个词两边的字串。
\B 非字符边界匹配
\d 数字字符匹配
\D 非数字字符匹配[^0-9]
\f 匹配换页符 \x0c 和 \cL
\n 匹配换行符 \x0a 和 \cJ
\r 匹配一个回车符。等效于\x0d 和 \cM
\s 匹配空白符,包括空格、制表符、换页符,相当于[\f\n\r\t\v]
\S 匹配非空白符
\t 匹配制表符,相当于\x09和\cl
\v 垂直制表符匹配,相当于\x0b和\cK
\w 匹配任何字类字符以及下划线。
\W 匹配非字类字符。
\xn 匹配n,n表示十六进制转义码。 \x41表示A。需要注意的是,这里的十六进制只能是两位数。\x041与\x04相同。

2017032514904405968065.png

Java语法

在Java中,主要使用如下几个类操作正则表达式。

Matcher类

索引方法

用于查看找到了什么有用的索引值。

1
2
3
4
5
6
7
8
//返回以前匹配的初始位置
public int start ()
//返回在以前的匹配操作
public int start ( int group )
//返回最后匹配字符之后的偏移量
public int end()
//返回在以前匹配操作期间,由给定组所捕获的子序列的最后字符之后的偏移量
public int end ( int group )

demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
String Regex = "\\bcat\\b";
String input = "cat cat cat cat cattie cat";

Pattern pattern = Pattern.compile(Regex);
Matcher matcher = pattern.matcher(input);
int count = 0;
while (matcher.find()) {
count++;
System.out.println("Match number " + count);
System.out.println("start() " + matcher.start());
System.out.println("end() " + matcher.end());
}
}

输出结果:
其中:

  • while循环find,每次从上次位置继续向后查找匹配的字段。
  • end标记的是匹配字段后的第一个位置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Match number 1
start() 0
end() 3
Match number 2
start() 4
end() 7
Match number 3
start() 8
end() 11
Match number 4
start() 12
end() 15
Match number 5
start() 23
end() 26

研究方法

用于检查输入字符串并返回一个布尔值,表示是非找到该模式。

1
2
3
4
5
6
7
8
//从区域开头开始的输入序列与该模式匹配
public boolean lookingAt();
//尝试查找与该模式匹配的输入序列的下一个子序列
public boolean find();
//重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列
publi boolean find(int start);
//尝试将整个区域与模式匹配
pulbic boolean matches();

Demo
其中,matches看起来就是仅判断串自身是不是符合,而不是匹配子串。

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
String Regex = "foo";
String input = "fooooooooooooooo";
Pattern pattern = Pattern.compile(Regex);
Matcher matcher = pattern.matcher(input);

System.out.println("Current Regex is " + Regex);
System.out.println("Current input is " + input);

System.out.println("lookingAt(): " + matcher.lookingAt());
System.out.println("matches(): " + matcher.matches());
}

输出结果:

1
2
3
4
Current Regex is foo
Current input is fooooooooooooooooo
lookingAt(): true
matches(): false

替换方法

1
2
3
4
5
6
7
8
9
10
//非终端添加和替换
public Matcher appendReplacement(StringBuffer sb,String replacement)
//终端添加和替换
public StringBuffer appendTail(StringBuffer sb)
//替换所有匹配字串
public String replaceAll(String replacement)
//替换给定第一个匹配字串
public String replaceFirst(String replacement)
//替换并返回被替换的字符串
public static String quoteReplacement(String s)

Demo

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
String regex = "dog";
String input = "The dog says meow. " + "All dogs say meow";
String replace = "cat";

Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
// input = matcher.replaceAll(replace);
input = matcher.replaceFirst(replace);
System.out.println(input);
}

输出结果:

1
The cat says meow. All dogs say meow

Demo2

1
2
3
4
5
6
7
8
9
10
String regex = "a*b";
String input = "aabfooaabfooabfoob";
String replace = "-";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
StringBuffer stringBuffer = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(stringBuffer, replace);
}
System.out.println(stringBuffer.toString());

将input字符串中所有的a*b通过循环一个个替换,结果如下:

1
-foo-foo-foo-


技术      Java Java基础

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!