正则表达式(Regular Expression)是一种字符串匹配模式,包括普通字符(例如,a到z之间的字母)和特殊字符(元字符),可以被用来匹配、拆分和替换字符串。
1.正则表达式的语法和功能
1.1匹配字符串
String类中的matches方法与equals方法类似,例如,以下两个语句结果都为true.
“Java”.matches(“Java”);
“Java”.equals(“Java”);
然而,matches方法功能更加强大,matches方法不仅可以匹配一个固定的字符串,还可以匹配符合一个模式的字符串集。例如,以下语句结果都为true.
“Java is fun”.matches(“Java.*”);
“Java is cool”.matches(“Java.*”);
“Java is powerful”.matches(“Java.*”);
以上语句中的“Java.*”是一个正则表达式,它描述了一个字符串模式,以Java开始,后面跟0个或多个字符串。其中,子字符串.*匹配0个或者多个任意字符。
1.1.1示例一
用正则表达式表示手机号码:
1.1.2示例二
用正则表达式表示QQ邮箱:
1.2正则表达式的语法
构造正则表达式就是用多种元字符与运算符将简单表达式结合起来创建一个复杂的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。它是一种由普通字符和特殊字符组成的文字模式。
1.2.1普通字符
包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。
字符 | 匹配 | 示例 |
[abc] | a、b或者c | Java匹配Ja[uvwx]a |
[^abc] | 除了a、b或者c以外的任意字符 | Java匹配Ja[^ars]a |
[A-Z] | A到Z | 匹配指定范围内的任意字符。 |
. | 任意单个字符,除了换行符之外 | Java匹配J..a |
[\S] | 非空白字符 | Java匹配[\\S]ava |
\w | 单词字符 | Java匹配[\\w]av[\\d] |
P{n,m} | n到m(不包括)次出现模式p | aaaa匹配“a{1,9}”; abb不匹配“a{2,9}bb” |
[a-e[m-p]] | a到e或者m到p | Java匹配[A-G[I-M]]av[a-d] |
[a-e&&[c-p]] | a到e与c到p的交集 | Java匹配[A-P&&[I-M]]av[a-d] |
1.2.2非打印字符
字符 | 描述 |
\n | 匹配一个换行符。 |
\t | 匹配一个制表符。 |
\r | 匹配一个回车符。 |
\s | 匹配任何空白字符,包括空格。 |
\S | 匹配任何非空白字符。 |
1.2.3特殊字符
许多元字符在匹配时,必须首先使字符"转义",即,将反斜杠字符\ 放在它们前面。
字符 | 描述 |
$ | 匹配输入字符串的结尾位置。用 \$匹配 $. |
() | 标记子表达式的开始和结束位置。使用 \( 和 \)匹配这些字符。 |
* | 匹配前面的子表达式零次或多次。用 \*匹配 * 字符。 |
+ | 匹配前面的子表达式一次或多次。用 \+匹配 + 字符。 |
. | 匹配除换行符 \n 之外的任何单字符。使用 \. 匹配 . 。 |
[ | 标记一个中括号表达式的开始。用 \[匹配 [。 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。 |
\ | 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "("。 |
^ | 匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 \^。 |
{ | 标记限定符表达式的开始。 |
| | 指明两项之间的一个选择。 |
1.2.4限定符
限定符可以限定一个正则表达式中一个给定组件的出现次数。
字符 | 描述 |
* | 匹配前面的子表达式零次或者多次。例如,ap*能匹配“a”以及“app”,等价于{0,}。 |
+ | 匹配前面的子表达式一次或者多次。例如,‘zo+’能匹配“zo”以及“zoo”,但不能匹配“z”,+等价于{1,}。 |
? | 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等价于 {0,1}。 |
{n} | n是一个非负整数。匹配n次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配“food”中的两个“o”。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "zooooo" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 |
{n,m} | m和n均为非负整数,且n<=m。最少匹配n次,最多匹配m次。例如,“o{1,3}”将匹配“zoooooo”中的前三个o。‘o{1,3}’等价于‘o?’。需注意逗号和两个数之间没有空格。 |
1.2.5定位符
定位符的功能是被用来描述一个字符串或者单词的边界,需注意的是由于在紧靠换行或者单词边界的前面后者后面不能有一个以上的位置,所以不能把定位符和限定符放在一起使用。
字符 | 描述 |
^ | 匹配输入字符串开始的位置。 |
$ | 匹配输入字符串结尾的位置。 |
\b | 匹配一个单词边界,即字于空格间的位置。 |
\B | 非单词边界匹配。 |
1.3拆分和替换字符串
String中包含的replaceAll、replaceFirst和split方法,分别用于替换和拆分字符串。其中,replaceAll方法是指替换所有匹配的字符串,replaceFirst方法是替换第一个匹配的子字符串。
split(regex)方法是指使用匹配的分隔符将一个字符串拆分为子字符串。
1.3.1替换字符串
1.3.1.1replaceAll方法
replaceAll方法:替换所有匹配的字符串。示例如下:
System.out.println(“Java Java Java”.replaceAll(“v\\w”,”wi”));
显示:
Jawi Jawi Jawi
1.3.1.2replaceFirst方法
replaceFirst方法:替换第一个匹配的子字符串。示例如下:
System.out.println(“Java Java Java”.replaceFirst(“v\\w”,”wi”));
显示:
Jawi Java Java
1.3.1.3贪婪匹配
默认条件下,所有量词都是“贪婪”的。意味着它们会尽可能多的匹配更多次。例如:
System.out.println(“Jaaavaa”.replaceFirst(“a+”,”R”));
显示“JRvaa“。因为第一个匹配成功的是aaa。
可以通过在后面添加“?“的形式来改变这种默认行为,把量词符变为”惰性“的,即让它匹配尽可能少的次数。例如,
System.out.println(“Jaaavaa”.replaceFirst(“a+?”,”R”));
显示“JRaavaa”,因为第一个匹配成功的是a。
1.3.2拆分字符串
1.3.2.1split(regex)方法以及split(regex,limit)方法
split(regex)方法是指使用匹配的分隔符将一个字符串拆分为子字符串。例如:
String[ ] tokens = “JavaHTML2Perl”.split(“\\d”);
以上语句是指将字符串“JavaHTML2Perl”拆分为Java、HTML、以及Perl并保存在token[0]、token[1]以及token[2]中。
而在split(regex,limit)方法中,limit参数确定模式匹配多少次,如果limit<=0,split(regex,limit)等同于split(regex)。如果limit>0,模式最多匹配limit-1次。示例如下:
“JavaHTML2Perl” .split(“\\d”); 拆分为Java,HTML,Perl
“JavaHTML2Perl” .split(“\\d”); 拆分为JavaHTML2Perl
“JavaHTML2Perl” .split(“\\d”); 拆分为Java,HTML2Perl
“JavaHTML2Perl” .split(“\\d”); 拆分为Java,HTML,Perl
“JavaHTML2Perl” .split(“\\d”); 拆分为Java,HTML,Perl
“JavaHTML2Perl” .split(“\\d”); 拆分为Java,HTML,Perl