先用正则表达式表达,然后,用Java语言实现。
开头:
这是我阅读了这篇文章http://www.jb51.net/tools/zhengze.html的过程中,想到的题目。
我觉得,学习正则表达式,要多做题。我就先自己构造题目,然后,读的差不多,就做题。
下述是构造的题目,然后,顺便将题目做了。排版混乱。
希望对阅读到该文的网友有帮助。
--------------------------------------------------------------
1.查找所有以0开头,后面跟着2-3个数字,然后是一个连字号“-”,最后是7或8位数字的字符串(像010-12345678或0376-7654321)。
(0d{2,3}-)(d{7} | d{8})为什么不正确
(0d{2,3}-)(d{7})|(0d{2,3}-)(d{8})
----直接在代码中写正则表达式的话,对要进行转移,比如下面将d,修改成\d:
package com.pattern.test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternTest {
public static void main(String[] args)
{
String pattern= "(0\d{2,3}-)(\d{7})|(0\d{2,3}-)(\d{8})" ;
String testStr= "0376-7654321";
// pattern = args[0];
// testStr = args[1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
if(matcher.find())
{
System. out.println(testStr+" matches pattern " + pattern);
} else
{
System. out.println(testStr+" does not match pattern " + pattern);
}
}
}
注意,如果pattern是作为args参数来提供的话,则无需对d进行转义。直接配置相应的正则表达式便可。
2.给定一段文章,查找hi这个单词。
hi
3.我要找出这样的一个字符串,包含is,然后,在is后面跟着一个perfect。
is.*perfect
package com.pattern.test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternTest {
public static void main(String[] args) {
String pattern = "\bis\b.*\bperfect\b";
String testStr = "RegexBuddy is your perfect companion for working with regular expressions";
// pattern = args [0];
// testStr = args [1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
if (matcher.find()) {
System. out.println("[" +testStr+"]" + " matches pattern " +"["+ pattern+"]" );
System. out.println("After replace, the new testStr is:[" + matcher.replaceFirst("TARGET" )+"]" );
System. out.println("the origl testStr is:[" + testStr+"]");
} else {
System. out.println("[" +testStr+"]" + " does not match pattern " + "["+ pattern+ "]");
}
}
}
-----
输出:
[RegexBuddy is your perfect companion for working with regular expressions] matches pattern [is.*perfect]
After replace, the new testStr is:[RegexBuddy TARGET companion for working with regular expressions]
the origl testStr is:[RegexBuddy is your perfect companion for working with regular expressions]
4.列举出你所知道的元字符,及它对应的含义。顺便解释元字符的含义。
, ., *,d,s,w,+,{6},{5,12},^,$,
1). ,表示一个位置,该位置占据的字符是空格,逗号,换行符。所以,可以使用
它来定义一个具体的单词,一个单词就是,is;或者一个任意的单词:
[a-zA-Z]{1,}
2). .表示一个字符,一个任意字符。
3). *,用于重复它前面的内容0次或多次。比如 .*表示有任意长的字符串。
is.*perfect,表示一个字符串,开头是is,然后跟着任意个字符,不是换行符,最后结束时prefest。匹配的
是这样一个字符串。
4). d,表示一个数字,0到9.
5). s,匹配任意的空白字符。
例如:
R.*sperfect
将会匹配具备这样特征的字符串,R开头,然后后面跟着若干字符,然后跟着若干空格,接着是perfect这个字符串。
6). +的含义与*的含义类似,只不过+表示1次或多次。
7). {6}表示前面的字符,重复6次。
比如:s{3},将会匹配,sss
8). {5,12}表示前面字符的数量是5到12个。比如:
s{3,5}
那么,对应的匹配字符:
sss,ssss,sssss,
9). ^匹配字符串的开始,$匹配字符串的结束。
比如:若不添加^,则输出结果是:
i:1[The is,The] matches pattern [The]
i:2[The is,The] matches pattern [The]
若添加^,则输出结果是:
i:1[The is,The] matches pattern [^The]
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternTest {
public static void main(String[] args) {
String pattern = "^The";
String testStr = "The is,The";
// pattern = args [0];
// testStr = args [1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
int i = 0;
while(matcher.find())
{
System. out.println(" i:" + (++i)+"["+testStr+ "]" + " matches pattern " +"["+ pattern+ "]");
}
}
}
---------例子------------------------
例如:使用The$,则匹配的是最后一个The。
输出结果是:
testStr:The is,The
The newOne: The is,Target
public class PatternTest {
public static void main(String[] args) {
String pattern = "The$";
String testStr = "The is,The";
// pattern = args [0];
// testStr = args [1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
while(matcher.find())
{
System. out.println("testStr:" + testStr);
System. out.println("The newOne: " + matcher.replaceFirst("Target" ));
}
}
}
5.实现这样一个匹配:检测输入的QQ号码,必须是5到12位数字。其它不匹配的字符串,排除掉。
d{5,12}
public class PatternTest {
public static void main(String[] args) {
String pattern = "\b\d{5,12}\b";
String testStr = "12345678,1234,12345,123456789012,1234567890123" ;
// pattern = args [0];
// testStr = args [1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
int i = 0;
while (matcher.find()) {
System. out.println("testStr:" + testStr);
System. out.println("The foundStr:" + matcher.group());
//替换操作
StringBuffer strBuf = new StringBuffer(testStr);
strBuf.replace(matcher.start(), matcher.end(), "Target" + (++i));
System. out.println("The newOne:" + strBuf.toString());
System. out.println("---------------------------------------" );
}
}
}
输出结果:
testStr:12345678,1234,12345,123456789012,1234567890123
The foundStr:12345678
The newOne:Target1,1234,12345,123456789012,1234567890123
---------------------------------------
testStr:12345678,1234,12345,123456789012,1234567890123
The foundStr:12345
The newOne:12345678,1234,Target2,123456789012,1234567890123
---------------------------------------
testStr:12345678,1234,12345,123456789012,1234567890123
The foundStr:123456789012
The newOne:12345678,1234,12345,Target3,1234567890123
---------------------------------------
6.解释,这两个正则表达式的含义,并给出符合要求的例子:aw*,d+,w{6}
1).aw* ---表示,匹配一个字符串,它是由字母a开头,后面跟任意个字符。
a,ab,dabc,a2sew,红色部分都会被匹配到。
2). d+,表示1个或多个数字字符。d表示1个字符。
例如:
public class PatternTest {
public static void main(String[] args) {
String pattern = "\ba\d+\b";
String testStr = "a,ab,dabc,a2sew,a2,a24";
// pattern = args [0];
// testStr = args [1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
int i = 0;
while (matcher.find()) {
System. out.println("testStr:" + testStr);
System. out.println("The foundStr:" + matcher.group());
//替换操作
StringBuffer strBuf = new StringBuffer(testStr);
strBuf.replace(matcher.start(), matcher.end(), "Target" + (++i));
System. out.println("The newOne:" + strBuf.toString());
System. out.println("---------------------------------------" );
}
}
}
输出结果:
testStr:a,ab,dabc,a2sew,a2,a24
The foundStr:a2
The newOne:a,ab,dabc,a2sew,Target1,a24
---------------------------------------
testStr:a,ab,dabc,a2sew,a2,a24
The foundStr:a24
The newOne:a,ab,dabc,a2sew,a2,Target2
---------------------------------------
如果,是d,则输出结果是:
testStr:a,ab,dabc,a2sew,a2,a24
The foundStr:a2
The newOne:a,ab,dabc,a2sew,Target1,a24
---------------------------------------
3).w{6},表示一个字符串,它有6个字符,这些字符类型是:字母或数字或下划线。
public class PatternTest {
public static void main(String[] args) {
String pattern = "\b\w{3}\b";
String testStr = "a_1,a12,abc,a8,a*+";
// pattern = args [0];
// testStr = args [1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
int i = 0;
while (matcher.find()) {
System. out.println("testStr:" + testStr);
System. out.println("The foundStr:" + matcher.group());
//替换操作
StringBuffer strBuf = new StringBuffer(testStr);
strBuf.replace(matcher.start(), matcher.end(), "Target" + (++i));
System. out.println("The newOne:" + strBuf.toString());
System. out.println("---------------------------------------" );
}
}
}
输出结果:
testStr:a_1,a12,abc,a8,a*+
The foundStr:a_1
The newOne:Target1,a12,abc,a8,a*+
---------------------------------------
testStr:a_1,a12,abc,a8,a*+
The foundStr:a12
The newOne:a_1,Target2,abc,a8,a*+
---------------------------------------
testStr:a_1,a12,abc,a8,a*+
The foundStr:abc
The newOne:a_1,a12,Target3,a8,a*+
---------------------------------------
7.分别写出可以将如下字符串匹配进来的正则表达式:deerchao.net,C:Windows
答:
deerchao.net
C:\Windows
用Java代码实现:
注意:我们的目标是让Java接收到\这个正则表达式中的字符串;然后,因为在Java中是有特殊含义的,所以,需要对它进行转义,因为我们需要输出两个,所以,需要进行两次转义。
这在Java中,是这样实现的: \\。这样就可以保证得到的字符串是\。
可以做个小实验,输出\\,然后得到的字符串是\。
如下:
System. out .println("\\" );
System. out .println("\\\" );
输出是:
\
\
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternTest {
public static void main(String[] args) {
String pattern = "C:\\Windows" ;
String testStr = "C:\Windows" ;
// pattern = args [0];
// testStr = args [1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
int i = 0;
while (matcher.find()) {
System. out.println( "testStr:" + testStr);
System. out.println( "The foundStr:" + matcher.group());
//替换操作
StringBuffer strBuf = new StringBuffer(testStr);
strBuf.replace(matcher.start(), matcher.end(), "Target" + (++i));
System. out.println( "The newOne:" + strBuf.toString());
System. out.println( "---------------------------------------" );
}
}
输出:
testStr:C:Windows
The foundStr:C:Windows
The newOne:Target1
---------------------------------------
public class PatternTest {
public static void main(String[] args) {
String pattern = "\bdeerchao\.net\b" ;
String testStr = "deerchao.net" ;
// pattern = args [0];
// testStr = args [1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
int i = 0;
while (matcher.find()) {
System. out .println("testStr:" + testStr);
System. out .println("The foundStr:" + matcher.group());
//替换操作
StringBuffer strBuf = new StringBuffer(testStr);
strBuf.replace(matcher.start(), matcher.end(), "Target" + (++i));
System. out .println("The newOne:" + strBuf.toString());
System. out .println("---------------------------------------" );
}
}
}
输出结果:
testStr:deerchao.net
The foundStr:deerchao.net
The newOne:Target1
---------------------------------------
8.如果要匹配的字符串中包含了元字符,那么,如何写这样的正则表达式。
答:要对元字符进行转义,比如,想在正则表达式中只是想匹配字符.,则这样做.。
例如:
public class PatternTest {
public static void main(String[] args) {
String pattern = "\.doc" ;
String testStr = "abc something.doc" ;
// pattern = args [0];
// testStr = args [1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
int i = 0;
while (matcher.find()) {
System. out .println("testStr:" + testStr);
System. out .println("The foundStr:" + matcher.group());
//替换操作
StringBuffer strBuf = new StringBuffer(testStr);
strBuf.replace(matcher.start(), matcher.end(), "Target" + (++i));
System. out .println("The newOne:" + strBuf.toString());
System. out .println("---------------------------------------" );
}
}
}
输出:
testStr:abc something.doc
The foundStr:.doc
The newOne:abc somethingTarget1
---------------------------------------
9.解释如下元字符的含义.,*, +, ?, {n},{n,},{n,m}
答:
1):
{n},表示重复前面字符n次,比如 a{3},匹配有3个a的字符串。
{n,},表示重复前面的字符大于等于n次,比如a{3,},匹配有3个a以上的字符串。
{n,m},表示重复前面的字符次数是n到m,比如a{3,4},匹配有3到4个a的字符串。
例如:
public class PatternTest {
public static void main(String[] args) {
String pattern = "a{3,4}" ;
String testStr = "aaaBc, aaBc, aaaaBc, aBc" ;
// pattern = args [0];
// testStr = args [1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
int i = 0;
while (matcher.find()) {
System. out .println("testStr:" + testStr);
System. out .println("The foundStr:" + matcher.group());
//替换操作
StringBuffer strBuf = new StringBuffer(testStr);
strBuf.replace(matcher.start(), matcher.end(), "Target" + (++i));
System. out .println("The newOne:" + strBuf.toString());
System. out .println("---------------------------------------" );
}
}
}
输出:
testStr:aaaBc, aaBc, aaaaBc, aBc
The foundStr:aaa
The newOne:Target1Bc, aaBc, aaaaBc, aBc
---------------------------------------
testStr:aaaBc, aaBc, aaaaBc, aBc
The foundStr:aaaa
The newOne:aaaBc, aaBc, Target2Bc, aBc
---------------------------------------
2):
【.】匹配,字母,数字,下划线。
例如:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternTest {
public static void main(String[] args) {
String pattern = "\b.\b" ;
String testStr = "a ? ) % & Bc 89 9 _" ;
// pattern = args [0];
// testStr = args [1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
int i = 0;
while (matcher.find()) {
System. out.println( "testStr:" + testStr);
System. out.println( "The foundStr:" + matcher.group());
//替换操作
StringBuffer strBuf = new StringBuffer(testStr);
strBuf.replace(matcher.start(), matcher.end(), "Target" + (++i));
System. out.println( "The newOne:" + strBuf.toString());
System. out.println( "---------------------------------------" );
}
}
}
输出:
testStr:a ? ) % & Bc 89 9 _
The foundStr:a
The newOne:Target1 ? ) % & Bc 89 9 _
---------------------------------------
testStr:a ? ) % & Bc 89 9 _
The foundStr:9
The newOne:a ? ) % & Bc 89 Target2 _
---------------------------------------
testStr:a ? ) % & Bc 89 9 _
The foundStr:_
The newOne:a ? ) % & Bc 89 9 Target3
---------------------------------------
3):
【*】表示重复前面的字符0次到n次。
比如:at*b,表示匹配这样一个字符串,以a开头,然后中间有0或若干个t,然后,结尾是b。
例如:
public class PatternTest {
public static void main(String[] args) {
String pattern = "\bat*b\b" ;
String testStr = "atb ab atttb " ;
// pattern = args [0];
// testStr = args [1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
int i = 0;
while (matcher.find()) {
System. out .println("testStr:" + testStr);
System. out .println("The foundStr:" + matcher.group());
//替换操作
StringBuffer strBuf = new StringBuffer(testStr);
strBuf.replace(matcher.start(), matcher.end(), "Target" + (++i));
System. out .println("The newOne:" + strBuf.toString());
System. out .println("---------------------------------------" );
}
}
}
输出:
testStr:atb ab atttb
The foundStr:atb
The newOne:Target1 ab atttb
---------------------------------------
testStr:atb ab atttb
The foundStr:ab
The newOne:atb Target2 atttb
---------------------------------------
testStr:atb ab atttb
The foundStr:atttb
The newOne:atb ab Target3
---------------------------------------
4):
【?】表示重复前面的字符0次或1次。例如:
at?b
然后,对于输入字符串:ab,atb,attb,
ab,atb符合模式。
5):
【+】表示重复前面的字符1次或多次,例如:
at+b
那么,对于输入字符串:ab,atb,attb,
atb,attb符合模式。
10.解析该正则表达式的含义,^d,并给出例子
答:
【^d】
对于一个要检测的字符串,匹配该字符串的开头,以数字开头。
比如,对于输入字符串:1,abc,1,de
那么,第一个1,会被匹配。
11.解释如下正则表达式的含义:
[aeiou],[.?!],[0-9],[a-z0-9A-Z_]
1):
"[aeiou]",表示匹配一个字符,该字符可以是a,e,i,o,u中的一种。
例如:
[aeiou]
对于输入字符串:a,aeiou,e,aeiou
匹配的字符串:a,e
2):
"[.?!]",表示匹配一个字符,该字符可以是.,?,!中的一种。
例如:
\ba[.?!]c\b
对于输入字符串:a?c a!c a.c .ab a??c
匹配的字符串:
a?c,a!c,a.c
3):
“[0-9]”,表示匹配一个字符,该字符是0到9中的一个字符。
"[a-z0-9A-Z]",表示匹配一个字符,该字符是0到9,a到z,A到Z中的一个字符。
12.解释如下正则表达式的含义:
((0d{2})d{8})|(0d{2}-d{8})
以例子解释:
(023)12345678,034-12345678,0123-12345678,0123-123456
那么,匹配的字符串是前面两个。
用Java实现匹配:
public class PatternTest {
public static void main(String[] args) {
String pattern = "(\(0\d{2}\)\d{8})|(0\d{2}-\d{8})" ;
String testStr = "(023)12345678,034-12345678,0123-12345678,0123-123456" ;
// pattern = args [0];
// testStr = args [1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
int i = 0;
while (matcher.find()) {
System. out .println("testStr:" + testStr);
System. out .println("The foundStr:" + matcher.group());
//替换操作
StringBuffer strBuf = new StringBuffer (testStr);
strBuf.replace(matcher.start(), matcher.end(), "Target" + (++i));
System. out .println("The newOne:" + strBuf.toString());
System. out .println("---------------------------------------" );
}
}
}
输出结果:
testStr:(023)12345678,034-12345678,0123-12345678,0123-123456
The foundStr:(023)12345678
The newOne:Target1,034-12345678,0123-12345678,0123-123456
---------------------------------------
testStr:(023)12345678,034-12345678,0123-12345678,0123-123456
The foundStr:034-12345678
The newOne:(023)12345678,Target2,0123-12345678,0123-123456
---------------------------------------
字符【(】,【)】,是用来分组的。字符【|】表示或,也就是,只要有一个分组符合条件之一,那么,就匹配。
上述正则表达式,匹配:开头有三个数字,然后用括号包围,然后是8为数字;开头有3为数字,然后用字符【-】连着,然后是8位数字。
13.解释如下正则表达式的含义:
0d{2}-d{8}|0d{3}-d{7},(?0d{2})?[- ]?d{8}|0d{2}[- ]?d{8},d{5}-d{4}|d{5}
1):
(0d{2}-d{8})|(0d{3}-d{7})
匹配的字符串具有如下两种特征:
034-12345678,0123-1234567
字符串中包含这样的字符串,它:开头是3个数字,以0开头,然后跟着-,然后跟着7个数字;开头是2个数字,以0开头,然后跟着-,然后跟着8个数字。
2):
((?0d{2})?[- ]?d{8})|(0d{2}[- ]?d{8})
表示的含义是:
匹配的字符串中,包含这样的字符串:它的开头可能有0个或1个(,然后是0,然后是两个数字,然后,是0个或1个,然后是0个或1个-,然后是8个数字;
开头是0,然后是两个数字,然后是0个或1个-,然后是8个数字。
所以,根据上述特征,下述字符串红色部分是匹配的:
(012)-12345678,012)-123456789,9(012-123456789,012-12345678,01212345678
3):
(d{5}-d{4})|(d{5})
这个则匹配包含具备这种类型的字符串:
5个数字,然后是-,然后是4个数字;5个数字。
例如,下述红色部分的字符串,会被匹配到:
12345-1234,12345,123456,123456-12345678
14.解释元字符 |的含义。
表示或的意思。如果你有多个正则表达式,只要字符串符合该多个正则表达式中的一个,那么,就挑选出该字符串。
例如:(d{5}-d{4})|(d{5})
15.解释如下正则表达式的含义:
(d{1,3}.){3}d{1,3},((2[0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd?)
1):
(d{1,3}.){3}d{1,3}
匹配具备这样特征的字符串,
前面是3个重复,该重复的字符串具备的特征是,具备1到3个数字和一个.,3个重复完了之后,跟着具备1到3个数字的字符串。
例如:
下述字符串,红色部分是被匹配到的:
123.123.123.567,wq13.124.123.5
2):
((2[0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd?)
首先,前面是3个重复,每个重复的末尾有.,然后只要具备如下特征(3个特征)之一便可:
2开头,后面跟一个字符(0到4中的一个),然后是一个字符(0到9);
25开头,然后跟着一个字符(0到5中的一个);
前面有0个或者1个字符(0或者1),然后跟一个字符(0到9),然后跟0个或1个字符(0到9中的一个)。
接着,跟一个匹配,该匹配具备如下特征(3个特征),只要具备如下特征之一便可:
2开头,然后跟一个字符(0到4中的一个),然后是一个字符(0到9);
25开头,然后跟一个字符(0到5中的一个);
以0个或1个字符开头(该字符是0或者1),然后跟一个字符(0到9),然后跟0个或一个字符(0到9)。
这个就是有效ip地址的匹配。
16.反义
1)写一个正则表达式,匹配除了数字以外的任意字符。
2)S+的含义,写出符合该匹配的字符串
3)<a[^>]+>,写出符合该匹配的字符串
4)解释如下元字符的含义:W,S,D,B,[^x],[^aeiou]
答:
1)d匹配数字;D,则表示匹配除了数字意外的字符。
比如:
aDb
那么对于输入字符串:
a*b,a(b,a9b,a*b,aub
匹配的字符串,有:
a*b,a(b,a*b,aub
2) S+,匹配这样的字符串,它不是空白字符,并且字符数量大于等于1.
比如:
对于输入字符串:
abc, ,*
红色部分是被匹配到的:
abc, ,*
3)<a[^>]+>
符合该匹配的字符串,
<a8>,
<a8>,
<a**>>,
<a23*(>
重点:a后面跟着1个或1个以上的非>字符;然后以>结尾。
4)
W,表示非下划线,字母,数字的字符。
例如例子:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternTest {
public static void main(String[] args) {
String pattern = "\ba\Wb\b" ;
String testStr = "a&b,acb,a_b,a9b,a*b,a(b,a!b" ;
// pattern = args [0];
// testStr = args [1];
Matcher matcher = Pattern. compile(pattern).matcher(testStr);
int i = 0;
while (matcher.find()) {
System. out .println("testStr:" + testStr);
System. out .println("The foundStr:" + matcher.group());
//替换操作
StringBuffer strBuf = new StringBuffer(testStr);
strBuf.replace(matcher.start(), matcher.end(), "Target" + (++i));
System. out .println("The newOne:" + strBuf.toString());
System. out .println("---------------------------------------" );
}
}
}
输出为:
testStr:a&b,acb,a_b,a9b,a*b,a(b,a!b
The foundStr:a&b
The newOne:Target1,acb,a_b,a9b,a*b,a(b,a!b
---------------------------------------
testStr:a&b,acb,a_b,a9b,a*b,a(b,a!b
The foundStr:a*b
The newOne:a&b,acb,a_b,a9b,Target2,a(b,a!b
---------------------------------------
testStr:a&b,acb,a_b,a9b,a*b,a(b,a!b
The foundStr:a(b
The newOne:a&b,acb,a_b,a9b,a*b,Target3,a!b
---------------------------------------
testStr:a&b,acb,a_b,a9b,a*b,a(b,a!b
The foundStr:a!b
The newOne:a&b,acb,a_b,a9b,a*b,a(b,Target4
---------------------------------------
S,D,B,[^x],[^aeiou]
则依次,表示非空白字符的任意字符;非数字的任意字符;非x的任意字符;非aeiou的任意字符。
---------------接下来是高级应用-----------------------------------