java学习-正则表达式

敲黑板!去练习!
熟能生巧熟能生巧熟能生巧……


1.很困惑一点就是,在牛客网上做的编程题整个copy到自己的编译器时候,运行不出来,给的提示错误是“找不到主函数”,然后发现自己没写main方法……(牛客网上只写了类)

注意【!!!】:
一定要有main方法才能执行该程序,规范的解释如下。
理论:java虚拟机通过main方法找到需要启动的运行程序,并且检查main函数所在类是否被java虚拟机装载。如果没有装载,那么就装载该类,并且装载所有相关的其他类。因此程序在运行的时候,第一个执行的方法就是main()方法。通常情况下,如果要运行一个类的方法,必须首先实例化出来这个类的一个对象,然后通过”对象名.方法名() “的方式来运行方法,但是因为main是程序的入口,这时候还没有实例化对象,因此将main方法声明为static的,这样这个方法就可以直接通过“类名.方法名() ”的方式来调用。

一个java文件中只能有一个public修饰的类,每个类中只能有一个main方法,所以一个java文件中可以有多个main方法。

也就是说,如果一个java文件有一个public修饰的类,那么java文件的名字,必须和这个public类的名字一样。

2.正则表达式regex:符合一定规则的字符串,是一种文本模式。

3.判断字符串不以0开头的语句:!str.startWith(“0”)

4.遍历字符串:
(非正则表达式形式)

1
2
3
4
5
6
7
char[] chs = str.toCharArray();
for(int x = 0;x < chs.length;x++){
char ch = chs[x];
if(!(ch>='0' && ch<='9')){
return false;
}
}

5.一个栗子的正则表达式:
如qq号码,共6-12位,只能是数字,第一位不能是0。

1
2
3
regex = "[1-9][0-9]{5,11}";
boolean flag = str.matches(regex);
return flag;

也等价于:

1
return str.matches("[1-9][0-9]{5,11}");

6.正则表达式的判断功能:用的就是上面的matches函数

public boolean matches(String regex)

7.正则表达式的分割功能:split函数,将串分割为几个数据

public String[] split(String regex)

如:

1
2
3
4
5
6
7
8
String ages = "20-28";
String regex = "-";
String[] ageArray = ages.split(regex);
for(int x = 0;x < ageArray.length;x++){
System.out.println(ageArray[x]);
}
int startAge = Integer.parseInt(ageArray[0]);
int endAge = Integer.parseInt(ageArray[1]);

若要切割一个路径,如E:\myblog\source\_posts,则

1
2
3
String str = "E:\\myblog\\source\\_posts";
String regex = "\\\\";
……

另一个栗子:
给一个数字的字符串排序,45 98 27 36 10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class RegexSort{
public static void main(String[] args){
String s = "45 98 27 36 10";
String[] strArray = s.split(" ");
int[] arr = new int[strArray.length];//定义int数组
//把字符串数组转化为int数组
for(int x = 0;x < arr.length;x++){
arr[x] = Integer.parseInt(strArray[x]);
}
Arrays.sort(arr);//对int数组进行排序
//把排序后的数组元素拼接得到一个字符串
StringBuilder sb = new StringBuilder();
for(int x = 0;x < arr.length;x++){
if(x == arr.length - 1){
sb.append(arr[x]);
}else{
sb.append(arr[x]).append(" ");
}
}
String result = sb.toString();
System.out.println(result);
}
}

8.正则表达式的替换功能:replaceAll函数

public String replaceAll(String regex,String replacement)

栗子:把数字替换成*号

1
2
3
4
5
6
7
8
9
10
11
//几个数字替换成一个*
String str = "hejiji2773hfjdhf7338kdj";
String regex = "\\d+";//一个或多个数字
String result = str.replaceAll(regex,"*");
System.out.println(result);
//一个数字替换成一个*
String str = "hejiji2773hfjdhf7338kdj";
String regex = "\\d";//一个数字
String result = str.replaceAll(regex,"*");
System.out.println(result);

9.正则表达式的获取功能:Pattern类和Matcher类

需要导入包:java.util.regex.Pattern;
java.util.regex.Matcher;
典型的调用顺序是:

1
2
3
4
5
6
7
//把正则表达式字符串通过compile方法编译生成模式对象
Pattern p = Pattern.compile("a*b");
//通过模式对象调用matcher方法,参数是被操作的字符串,返回一个匹配器对象
Matcher m = p.matcher("aaaab");
//用匹配器进行匹配
boolean b = m.matches();
System.out.println(b);

栗子:
把这个字符串中的三个字符组成的单词找出来:zhu yi la,ming tian fang jia

步骤是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
String str = "zhu yi la,ming tian fang jia";
String regex = "\\b[a-z]{3}\\b";//前后都必须是单词边界
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
//注意:获取之前,一定要先判断是否存在满足条件的数据
//public boolean find()
//boolean flag = m.find();
//System.out.println(flag);
//输出true or false
//public String group()
//String s = m.group();
//System.out.println(s);
//输出单词
//上两段归结为下面的两行:
while(m.find()){
System.out.println(m.group());
}

10.字符:
x 表示字符x
\\ 反斜线字符
\r 回车
\n 换行

字符类:
[abc] a、b或c(简单类)
[^abc] 任何字符,除了a、b或c(否定)
[a-zA-Z] a-z或A-Z(范围)
[0-9] 0到9的数字字符

预定义字符类:
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\w 单词字符:[a-zA-Z_0-9](在正则表达式中可以组词单词的字符)

边界匹配器:
^ 行的开头
$ 行的结尾(^helloworld$)
\b 单词边界(非单词字符)

数量词:
x? :x,一次或一次也没有(1或0)
x* :x,零次或多次(大于等于0)
x+ :x,一次或多次(大于等于1)
x{n} :x,恰好n次
x{n,m} :x,至少n次,但是不超过m次

【emmmmm……虽然和下面的题不是很匹配,不过就是这个知识点嘛】

10.年-月-日:^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-((0-2)|(3[0|1]))$
(有些不规范)

这次做的题:

请实现一个函数用来匹配包括’.’和’‘的正则表达式。模式中的字符’.’表示任意一个字符,而’‘表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串”aaa”与模式”a.a”和”abaca”匹配,但是与”aa.a”和”ab*a”均不匹配。

解答(参照大佬的答案):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Solution {
public boolean match(char[] str, char[] pattern){
if(str == null || pattern == null){
return false;
}
int strIndex = 0;
int patternIndex = 0;
return getMatch(str,strIndex,pattern,patternIndex);
}
public boolean getMatch(char[] str,int strIndex,char[] pattern,int patternIndex){
//有效性检验
if(strIndex == str.length && patternIndex == pattern.length){
return true;
}
if(strIndex != str.length && patternIndex == pattern.length){
return false;
}
if(patternIndex + 1 < pattern.length && pattern[patternIndex + 1] == '*'){
if((strIndex != str.length && pattern[patternIndex] == str[strIndex]) || (pattern[patternIndex] == '.' && strIndex != str.length)){
return getMatch(str,strIndex,pattern,patternIndex + 2)
||getMatch(str,strIndex + 1,pattern,patternIndex)
||getMatch(str,strIndex + 1,pattern,patternIndex + 2);
}
return getMatch(str,strIndex,pattern,patternIndex + 2);
}
if((strIndex != str.length && pattern[patternIndex] == str[strIndex]) || (pattern[patternIndex] == '.' && strIndex != str.length)){
return getMatch(str,strIndex + 1,pattern,patternIndex + 1);
}
return false;
}
}


9.25

做的另一个和正则表达式密切相关的题:

题目:
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串”+100”,”5e2”,”-123”,”3.1416”和”-1E-16”都表示数值。 但是”12e”,”1a3.14”,”1.2.3”,”+-5”和”12e+4.3”都不是。

解答:

1
2
3
4
5
6
7
8
9
10
11
public class Solution {
public boolean isNumeric(char[] str) {
String s = String.valueOf(str);
//首位正负号0或1次
//数字包括整数或小数
//e或E
//有e的话后面接正负整数
//无e的话后面整个没有
return s.matches("^([+-]?\\d*(\\.\\d*)?)([eE][+-]?(\\d+))?");
}
}