正则表达式和算法水题
牛牛写情书
https://ac.nowcoder.com/acm/problem/247576
先来看常规解法
我们先把字符串每个字符遍历,将符合条件的字符加到字符串上
然后再调用String包下的contains方法 直接判断是否匹配
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
String s = sc.next();
String k = sc.next();
String ss = "";
for(int i = 0; i < n; i++) {
if (s.charAt(i) >= 'a' && s.charAt(i) <= 'z'){
ss += s.charAt(i);
}
}
if(ss.contains(k)) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
}
这是正则表达式解法
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
String s = sc.next();
String k = sc.next();
s = s.replaceAll("[^a-z]", "");
System.out.println((s.indexOf(k)<0)?"NO":"YES");
}
}
同样是调用String包下的replace方法进行去除不符合的字符
注意replace方法重载
要选择参数是正则表达式和字符串的那个方法
然后再调用indexOf方法
用于查找位置,虽说indexOf方法也重载
下面是常见的传入参数方式
正则表达式
正则表达式可以校验一个字符串是否格式合法
以前我们的核心思想是
把异常数据拿出考虑 过滤
将留下满足的数据通过
从左往右依次书写
[1-9]表示0不能防止开头
\ \d表示都是数字
{5,19}表示后面有5—19位
下面是书写格式查找表
下面是实例操作
public static void main(String[] args) {
//正则表达式练习
System.out.println("a".matches("[abc]"));//true
System.out.println("ab".matches("[abc]"));//false
System.out.println("z".matches("[abc]"));//false
System.out.println("ab".matches("[abc][abc]"));//true
//表示只能出现一次
System.out.println("a".matches("[^abc]"));//false
System.out.println("f".matches("[^abc]"));//true
System.out.println("zz".matches("[^abc]"));//false
System.out.println("zz".matches("[^abc][^abc]"));//true
//表示是否不出现
System.out.println("a".matches("[a-z]"));//true
System.out.println("A".matches("[a-zA-Z]"));//true
System.out.println("aa".matches("[a-z]"));//false
System.out.println("aa".matches("[a-z][a-z]"));//true
System.out.println("0".matches("[a-zA-Z]"));//false
System.out.println("0".matches("[a-zA-Z0-9]"));//true
System.out.println("0".matches("[0-9]"));//true
//范围的判断 a-z和A-Z
System.out.println("a".matches("[a-d[m-p]]"));//true
System.out.println("0".matches("[a-d[m-p]]"));//false
//范围的判断 a-z或者A-Z
System.out.println("a".matches("[a-z&&[def]]"));//false
System.out.println("a".matches("[a-z&[def]]"));//true
System.out.println("&".matches("[a-z&&[def]]"));//false
System.out.println("1".matches("[a-z&&[def]]"));//false
//范围的判断 求交集a-z和def的 是否全都有
//如果写成&就是一个简简单单的且符号
System.out.println("a".matches("[a-z&&[^bc]]"));//true
System.out.println("a".matches("[a-z&&[^b-c]]"));//true
//范围的判断 a-z和非bc的交集
}
转义字符
\在java中是转义字符
改变后面字符的原本含义
比如
通过路径访问时
\ \前面的\表示将后面的\转化成一个普通的\
System.out.println("你".matches(".."));//false
System.out.println("你A".matches(".."));//true
//判断是否为一个字符
System.out.println("1".matches("\\d"));//true
System.out.println("11".matches("\\d"));//false
System.out.println("11".matches("\\d\\d"));//true
//判断是否为一个数字
System.out.println("z".matches("\\w"));//true
System.out.println("z".matches("\\w"));//true
System.out.println("2".matches("\\w"));//true
System.out.println("21".matches("\\w"));//false
System.out.println("你".matches("\\w"));//false
System.out.println("_".matches("\\w"));//true
// \\w只能是一位单词字符 [a-zA-Z_0-9] 大写的W是取反
//小写 大写 下划线 数字
System.out.println("你".matches("\\W"));//false
数量词
正则表达式构造在Pattern类里面
打开API帮助文档查看
演示
System.out.println("23_f".matches("[a-zA-Z0-9]{4}"));//false
System.out.println("23_f".matches("[\\w&&[^_]]{4}"));//false
System.out.println("23df".matches("[\\w&&[^_]]{4}"));//true
操作案例
public static void main(String[] args) {
//正则表达式练习
System.out.println("a".matches("[abc]"));//true
System.out.println("ab".matches("[abc]"));//false
System.out.println("z".matches("[abc]"));//false
System.out.println("ab".matches("[abc][abc]"));//true
//表示只能出现一次
System.out.println("a".matches("[^abc]"));//false
System.out.println("f".matches("[^abc]"));//true
System.out.println("zz".matches("[^abc]"));//false
System.out.println("zz".matches("[^abc][^abc]"));//true
//表示是否不出现
System.out.println("a".matches("[a-z]"));//true
System.out.println("A".matches("[a-zA-Z]"));//true
System.out.println("aa".matches("[a-z]"));//false
System.out.println("aa".matches("[a-z][a-z]"));//true
System.out.println("0".matches("[a-zA-Z]"));//false
System.out.println("0".matches("[a-zA-Z0-9]"));//true
System.out.println("0".matches("[0-9]"));//true
//范围的判断 a-z和A-Z
System.out.println("a".matches("[a-d[m-p]]"));//true
System.out.println("0".matches("[a-d[m-p]]"));//false
//范围的判断 a-z或者A-Z
System.out.println("a".matches("[a-z&&[def]]"));//false
System.out.println("a".matches("[a-z&[def]]"));//true
System.out.println("&".matches("[a-z&&[def]]"));//false
System.out.println("1".matches("[a-z&&[def]]"));//false
//范围的判断 求交集a-z和def的 是否全都有
//如果写成&就是一个简简单单的且符号
System.out.println("a".matches("[a-z&&[^bc]]"));//true
System.out.println("a".matches("[a-z&&[^b-c]]"));//true
//范围的判断 a-z和非bc的交集
System.out.println("\"");
System.out.println("你".matches(".."));//false
System.out.println("你A".matches(".."));//true
//判断是否为一个字符
System.out.println("1".matches("\\d"));//true
System.out.println("11".matches("\\d"));//false
System.out.println("11".matches("\\d\\d"));//true
//判断是否为一个数字
System.out.println("z".matches("\\w"));//true
System.out.println("z".matches("\\w"));//true
System.out.println("2".matches("\\w"));//true
System.out.println("21".matches("\\w"));//false
System.out.println("你".matches("\\w"));//false
System.out.println("_".matches("\\w"));//true
System.out.println("你".matches("\\W"));//false
// \\w只能是一位单词字符 [a-zA-Z_0-9] 大写的W是取反
//小写 大写 下划线 数字
System.out.println("23df".matches("[a-zA-Z0-9]{4}"));//true
System.out.println("23_f".matches("[a-zA-Z0-9]{4}"));//false
System.out.println("23_f".matches("[\\w&&[^_]]{4}"));//false
System.out.println("23df".matches("[\\w&&[^_]]{4}"));//true
}
}
正则表达式练习
正则表达式书写时应该拿正确的数据从左往右依次书写
校验输入的手机号码
校验输入的邮箱号
校验输入的电话号码
是否符合要求
public class Main {
public static void main(String[] args) {
//心得
//拿一个正确的数据。从左往右依次去写
//手机号码 13112345678
//分成三部分
// 1表示手机号码只能是1开头,
// [3-9]表示手号码第二位只能是3-9之间的
// \\d{9}表示任意数字可以出现9次
String regex1="1[3-9]\\d{9}";
//座机号码 020-2324242
//分为三部分
// 0\\d{2,3}表示一定以0开头 从第二位开始可以是任意数字出现2-3次
// ?表示次数,出现1次或者0次
// 号码的第一位不能以0开头,从第二位开始可以是任意数字,一共5-10位
String regex2="0\\d{2,3}-?[1-9]\\d{4,9}";
System.out.println("021224422".matches(regex2));
//邮箱号码 323232@qq.com zhangsan@qq.com dlei009@pei.com.cn
//分成三部分
// @的左边 \\w+ 表示出现任意字母大小写数字 至少出现一次
// @表示必须出现一次
// 分成三小段
// [\w^_]表示任意大小写字母数字去掉下划线{2,6}由2-6次
// \\.表示必须出现一个点 .表示出现任意一个字符
// [a-zA-Z]{2,3}表示出现2到3位的任意大小写字母
// 括号括起来表示那一部分可以出现一次到两次 看成一组
String regex3="\\w+@\\[\\w^_]{2,6}(\\.[a-zA-Z]{2,3}){1,2}";
}
}
在实际后端开发中,我们很少会自己写正则表达式
通常都是百度一个类似的,自己改成公司要求
要求能看的懂即可
下面是我用idea插件获取的正则表达式
| 表示或者的意思
0和1加上任意一个整数 或者 2加上0或1或2
0-5加上任意一个数字
0-5加上任意一个数字
方括号里表示三种方式只要出现一次就可以了
(?i)表示忽略后方字符串的大小写
身份证校验
前六位是省份 市区 派出所信息
第一位不能是0 [1-9]\ \d{5}
然后是出生日期
年份 {18|19|20} \ \d{2}
月份 01-09 10 11 12 0[1-9]|[0-2]
日期01-31 0[1-9] | [12]\ \d |3[01]
后面四位 先任意出现3次数字 \ \d{3}
最后一位可以是一位数字或xX [\ \dXx]**
最后拼起来一起 用括号
那么正则表达式就是
鼠标右键 用插件搜索 然后插入
我们只需要对现有的需求进行一些改写即可
下面是资料
下面是我的心得和尝试
public class Main {
public static void main(String[] args) {
//心得
//拿一个正确的数据。从左往右依次去写
//手机号码 13112345678
//分成三部分
// 1表示手机号码只能是1开头,
// [3-9]表示手号码第二位只能是3-9之间的
// \\d{9}表示任意数字可以出现9次
String regex1="1[3-9]\\d{9}";
//座机号码 020-2324242
//分为三部分
// 0\\d{2,3}表示一定以0开头 从第二位开始可以是任意数字出现2-3次
// ?表示次数,出现1次或者0次
// 号码的第一位不能以0开头,从第二位开始可以是任意数字,一共5-10位
String regex2="0\\d{2,3}-?[1-9]\\d{4,9}";
System.out.println("021224422".matches(regex2));
//邮箱号码 323232@qq.com zhangsan@qq.com dlei009@pei.com.cn
//分成三部分
// @的左边 \\w+ 表示出现任意字母大小写数字 至少出现一次
// @表示必须出现一次
// 分成三小段
// [\w^_]表示任意大小写字母数字去掉下划线{2,6}由2-6次
// \\.表示必须出现一个点 .表示出现任意一个字符
// [a-zA-Z]{2,3}表示出现2到3位的任意大小写字母
// 括号括起来表示那一部分可以出现一次到两次 看成一组
String regex3="\\w+@\\[\\w^_]{2,6}(\\.[a-zA-Z]{2,3}){1,2}";
String sfz="/(^\\d{8}(0\\d|10|11|12)([0-2]\\d|30|31)\\d{3}$)|(^\\d{6}(18|19|20)\\d{2}(0[1-9]|10|11|12)([0-2]\\d|30|31)\\d{3}(\\d|X|x)$)/";
}
}