摘要
很多博客都以 “知道这些正则表达式你可以少些XX行代码” 作为标题,但是总是记不住正则的全部语法,也不太能够白板写一个正则匹配,所以整理了一份基础用法。
正则表达式语法
字符
说明
\
将下一个字符标记为特殊字符、文本、反向引用或八进制转义符。例如\n。
^
表示下面一个字符是开始的位置。如果设置了Multiline
属性,^
会表示与\n
或\r
之后的位置匹配。(也就是每行开头匹配)。
$
表示匹配行尾,其他特性同^。
*
*闭包。
+
+闭包。
?
表示前面的字符出现1次或0次,相当于{0,1} 。
{n}
n必须为非负数,匹配前面的字符至少出现{n}次。例如, o{2} 可以匹配boo
的o
,但不能找到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相同。
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.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通过循环一个个替换,结果如下: