在做实验二时,我遇到了读入数据的问题,那个问题要求读入一段文字并进行处理,将之变成一个有向图。
我写出的方案:
Scanner s = new Scanner(new BufferedReader(new FileReader(corpus)))
while (s.hasNext()) {
words.add(s.next().toLowerCase());
}
这是满足那个试验要求的,但是,随着课程的推进,我了解到了正则表达式这一知识点,明白了它也可以满足程序员按照特定的模式进行读值,从而更加符合编程的要求,在经过查阅相关资料后,发现了java的正则表达式是需要Pattern类和Matcher类来实现的。
首先,java与正则表达式相关的工具主要在java.util.regex包中;这个包中主要有两个类:Pattern类、Matcher类。
Pattern:
Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法只能通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式, 这也是我们所学到过得工厂方法,这代表它的构造方法是私有的。
例如:
Pattern p = Pattern.compile("[\\w']+");
p.pattern();
p.pattern() 返回得失正则表达式的字符串形式,就是regex的形式。
Matcher
Matcher类的构造方法和Pattern类一样,也是私有的,不能随意创建,只能通过Pattern.matcher(CharSequence input)方法获得一个Matcher对象。
例如:
Matcher m = p.matcher(textFromFile);
Matcher类提供了对正则表达式的分组方法,以及对正则表达式多次匹配的方法,这就弥补了Pattern类的不足之处,这样就使得正则匹配操作边的更加强大。
Matcher对于匹配提供了三个方法:分别是Matcher.matches()、 Matcher.lookingAt()、 Matcher.find()。这三个方法均返回boolean类型,当匹配时返回true,若不匹配到则返回false。
(一)Matcher.matches()
Matcher.matches()是对整个字符串进行匹配,只有整个字符串都匹配成功,才能返回true 。
例如:
Pattern p=Pattern.compile("\\d+");
Matcher m1=p.matcher("369258");
boolean a = m1.matches();
Matcher m2=p.matcher("157aa571");
boolean b = m2.matches();
System.out.println(a+","+b);
结果为:
(二)Matcher.lookingAt()
Matcher.lookingAt()对整个字符串最前面的字符进行匹配,只有满足的的字符串部分在最前面才返回true ,否则就返回false。
例如:
Pattern p=Pattern.compile("\\d+");
Matcher m1=p.matcher("369258qwer");
boolean a = m1.lookingAt();
Matcher m2=p.matcher("qwer157aa571");
boolean b = m2.lookingAt();
System.out.println(a+","+b);
结果为:
(三)Matcher.find()
Matcher.find()是对字符串各个部分进行匹配,只要整个字符串中能匹配到的满足条件的字符串就可以返回true,否则就要false。
例如:
Pattern p=Pattern.compile("\\d+");
Matcher m1=p.matcher("369258qwer");
boolean a = m1.find();
Matcher m2=p.matcher("qwer157aa");
boolean b = m2.find();
Matcher m3=p.matcher("qwer159");
boolean c = m3.find();
Matcher m4=p.matcher("qwer");
boolean d = m4.find();
Matcher m5=p.matcher("=====");
boolean e = m5.find();
System.out.println(a+","+b+","+c+","+d+","+e);
结果为:
Matcher类除了上面的三种匹配方法外,还有其他的一些方法对字符串进行处理,例如:Mathcer.start()、Matcher.end()、Matcher.group()。
(四)Mathcer.start()
Mathcer.start()返回的是匹配到的子字符串在字符串中的索引位置。(从0开始)
例如:
Pattern p=Pattern.compile("\\d+");
Matcher m1=p.matcher("369258qwer");
Matcher m2=p.matcher("qwer157aa");
m1.find();
m2.find();
System.out.println(m1.start()+","+m2.start());
结果为:
(五)Mathcer.end()
Mathcer.end()与Mathcer.start()相反,它返回的是匹配到的子字符串的最后一个字符在字符串中的索引位置.。
例如:
Pattern p=Pattern.compile("\\d+");
Matcher m1=p.matcher("369258qwer");
Matcher m2=p.matcher("qwer157aa");
m1.find();
m2.find();
System.out.println(m1.end()+","+m2.end());
结果为:
(六)Mathcer.group()
Mathcer.group()返回的是匹配到的子字符串,并且它没有参数时默认返回的是第一个满足要求的子字符串的全部部分。但如果添加参数就可以返回你想要的次序的字符子串部分。如:group(0)就是指的整个串,group(1) 指的是第一个括号里的东西,group(2)指的第二个括号里的东西。
例如 :
Pattern p=Pattern.compile("(\\d+)([a-z]+)");
Matcher m1=p.matcher("369258qwer");
Matcher m2=p.matcher("qwer157aa");
Matcher m3=p.matcher("369258qwer15788");
m1.find();
m2.find();
m3.find();
System.out.println(m1.group()+","+m2.group()+","+m3.group()+","+m3.group(2));
结果为:
这样,Pattern类和Matcher类的主要运用方法就学习完了,对于实验二的那个句子可以改为:
String textFromFile = String.join("", lines);
Pattern p = Pattern.compile("[\\w']+");
Matcher m = p.matcher(textFromFile);
while (m.find()) {
words.add(textFromFile.substring(m.start(), m.end()).toLowerCase());
}
这样就可以完成用正则表达式来进行信息读入的步骤。