第1关:学习-Java常用类之Pattern和Matcher类
任务描述
本关任务:校验键盘输入的 QQ 号是否合格。
相关知识
我们的字符串 String 类中包含了正则的匹配、字符的替换等操作,但是,有的时候 String 的正则匹配不能够满足要求,这时我们就需要用到 Pattern 和 Matcher 类。
Pattern
Pattern 类的主要作用是给正则表达式一个匹配模式,因为在 Java 里面正则表达式是一个字符串,字符串的能力是非常有限的,不能指定全局匹配、区分大小写匹配和多行匹配。因此在 Java 里面需要 Pattern 实例来包装正则表达式字符串,然后通过 Pattern 实例的方法来设置匹配模式。
要想引用 Pattern 类,首先我们需要导包:
import java.util.regex.Pattern;
我们来看 Pattern 类的一些常用方法:
-
Pattern complie(String regex):由于 Pattern 的构造函数是私有的,不可以直接创建,所以通过静态方法 compile(String regex) 方法来创建,将给定的正则表达式编译并赋予给 Pattern 类;
Pattern p = Pattern.compile("\\w+"); // 编译一个正则表达式并返回一个编译好的 Pattern 对象
-
String pattern():返回正则表达式的字符串形式,其实就是返回 Pattern.complile(String regex) 的 regex 参数;
String regex = "\\w+";
Pattern pattern = Pattern.compile(regex);
String str = pattern.pattern(); // 返回正则表达式的字符串形式
System.out.println(str);
执行结果:
\w+
-
Pattern compile(String regex, int flags):方法功能和 compile(String regex) 相同,不过增加了 flag 参数,flag 参数用来控制正则表达式的匹配行为,可取值范围如下:
-
Pattern.CASE_INSENSITIVE:默认情况下,大小写不敏感的匹配只适用于 US-ASCII 字符集。这个标志能让表达式忽略大小写进行匹配;
-
Pattern.COMMENTS:在这种模式下,匹配时会忽略(正则表达式里的)空格字符(不是指表达式里的"\s",而是指表达式里的空格,tab,回车之类)。注释从#开始,一直到这行结束;
-
Pattern.DOTALL:在这种模式下,表达式'.'可以匹配任意字符,包括表示一行的结束符。默认情况下,表达式'.'不匹配行的结束符;
-
Pattern.MULTILINE:在这种模式下,'^'和'$'分别匹配一行的开始和结束。此外,'^'仍然匹配字符串的开始,'$'也匹配字符串的结束。默认情况下,这两个表达式仅仅匹配字符串的开始和结束;
-
Pattern.UNICODE_CASE:在这个模式下,如果你还启用了 CASE_INSENSITIVE 标志,那么它会对 Unicode 字符进行大小写不敏感的匹配。默认情况下,大小写不敏感的匹配只适用于 US-ASCII 字符集;
-
Pattern.UNIX_LINES:在这个模式下,只有'\n'才被认作一行的中止,并且与'.','^',以及'$'进行匹配。
Pattern pattern = Pattern.compile("\\?{2}",Pattern.CASE_INSENSITIVE);
-
-
int flags():返回当前 Pattern 的匹配 flags 参数;
-
Pattern.matcher(CharSequence input):对指定输入的字符串创建一个 Matcher 对象。Matcher 对象一般通过这个方法生成。CharSequence 是个 interface,String 类实现了 CharSequence 接口,因此可以传入 String 类型的值。
Pattern pattern = Pattern.compile("\\?{2}");
Matcher matcher = pattern.matcher("??");
//matcher 的 matches 方法是对字符串整合匹配。只有整个字符串符合正则表达式才会返回 true
boolean matches = matcher.matches();
执行结果:
true
-
String[] split(CharSequence input):根据正则表达式分割传入的这个字符串。
-
String[] split(CharSequence input, int limit):功能和 String[] split(CharSequence input) 相同,增加参数 limit 目的在于要指定分割的段数。
Pattern pattern = Pattern.compile("[#_-]");
String str = "he#llo_wor_ld-!";
String[] arrays = pattern.split(str, 4); // 根据正则表达式分隔字符串,将其分割为 4 段
for (String s : arrays) {
System.out.println(s);
}
执行结果:
he
llo
wor
ld-!
Matcher
Matcher 类使用 Pattern 实例提供的模式信息对正则表达式进行匹配。
以下是 Matcher 类的一些常用方法:
-
boolean matches():尝试对整个目标字符展开匹配检测,也就是只有整个目标字符串完全匹配时才返回 true;
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
System.out.println(b);
执行结果:
true
-
boolean lookingAt():对前面的字符串进行匹配,只有匹配到的字符串在最前面才会返回 true;
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("22bb23");
boolean match = m.lookingAt(); // 对前面的字符串进行匹配
System.out.println(match);
m = p.matcher("bb2233");
match= m.lookingAt(); // 对前面的字符串进行匹配
System.out.println(match);
执行结果:
true
false
-
boolean find():对字符串进行匹配,匹配到的字符串可以在任何位置;
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("22bb23");
System.out.println(m.find()); // 对字符串进行匹配
Matcher m2 = p.matcher("aabb");
System.out.println(m2.find()); // 对字符串进行匹配
执行结果:
true
false
-
int start():返回当前匹配到的字符串在原目标字符串中的位置;
-
int end():返回当前匹配的字符串的最后一个字符在原目标字符串中的索引位置;
-
String group():返回匹配到的子字符串。
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("aa22bb23");
m.find();
int start = m.start(); // 返回当前匹配到的字符串在原目标字符串中的位置
String group = m.group(); // 返回匹配到的子字符串
int end = m.end(); // 返回当前匹配的字符串的最后一个字符在原目标字符串中的索引位置
System.out.println(start);
System.out.println(end);
System.out.println(group);
执行结果:
2
4
22
-
public String replaceAll(String replacement):代替每一个输入序列的子序列,与给出的代替字符串的模式匹配;
String str = "{0x40, 0x31, 0x20, 0x00}";
String regex = "([0-9A-Za-z]+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
String replacedAllStr = matcher.replaceAll("replace"); // 代替每一个输入序列的子序列
System.out.println("replaced : " + replacedAllStr);
执行结果:
replaced : {replace, replace, replace, replace}
-
public String replaceFirst(String replacement):代替第一个输入序列的子序列,与给出的代替字符串的模式匹配;
String str = "{0x40, 0x31, 0x20, 0x00}";
String regex = "([0-9A-Za-z]+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
String replacedFirstStr = matcher.replaceFirst("replace"); // 代替第一个输入序列的子序列
System.out.println("replaced first : " + replacedFirstStr);
执行结果:
replaced first : {replace, 0x31, 0x20, 0x00}
-
public StringBuffer appendTail(StringBuffer sb):将最后一次匹配工作后剩余的字符串添加到一个 StringBuffer 对象里;
-
Matcher appendReplacement(StringBuffer sb, String replacement):将当前匹配子串替换为指定字符串,并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个 StringBuffer 对象里(需while(matcher.find())进行配合迭代);
String str = "{0x40, 0x31, 0x20, 0x00}";
String regex = "([0-9A-Za-z]+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
StringBuffer appendRepStr = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(appendRepStr,"0xffff"); // 将当前匹配子串替换为指定字符串,并将其添加到 appendRepStr 中
}
System.out.println(appendRepStr);
matcher.appendTail(appendRepStr); // 将最后一次匹配工作后剩余的字符串添加到 appendRepStr 对象里
System.out.println(appendRepStr);
执行结果:
{0xffff, 0xffff, 0xffff, 0xffff
{0xffff, 0xffff, 0xffff, 0xffff}
-
public static String quoteReplacement(String s):返回一个特定字符串逐字替换的字符串。这个方法产生了一个字符串将作为文本替换的 Matcher 类的 appendreplacement 方法。
编程要求
仔细阅读右侧编辑区内给出的代码框架及注释,在 Begin-End 中校验键盘输入的 QQ 号是否合格,判定合格的条件如下:
-
要求必须是 5-15 位;
-
0 不能开头;
-
必须都是数字;
-
如果合格,输出:“你输入的QQ号验证成功”;否则,输出:“你输入的QQ号验证失败”。
测试说明
平台将使用测试集运行你编写的程序代码,若全部的运行结果正确,则通关。 可在右侧“测试结果”区查看具体的测试集详情。
测试输入:
02546954v
预期输出:
你输入的QQ号验证失败
开始你的任务吧,祝你成功!
源代码:
/**
* 校验键盘输入的 QQ 号是否合格。
*/
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test{
public static void main(String[] args) {
// 请在下面的Begin-End之间编写正确的代码
/********** Begin **********/
Scanner input = new Scanner(System.in);
String str = input.next();
Pattern pattern = Pattern.compile("^[1-9][0-9]+$");//'^'匹配字符串的开始,'$'匹配字符串的结束
int l = str.length();
Matcher m = pattern.matcher(str);
boolean b = m.matches();//匹配
if ((l >= 5 & l <= 15) & b){ //5-15位
System.out.println("你输入的QQ号验证成功");
}else {
System.out.println("你输入的QQ号验证失败");
}
/********** End **********/
}
}