java常用工具(正则表达式、crontab表达式、常用小工具......)

正则表达式

基础语法

x|y:匹配单个字符x或者单个字符y
[xyz]:匹配指定(xyz)字符的任意一个
[^xyz]:匹配非(xyz)字符的任意一个
[0-9]:匹配范围;表示0到9的任意一个数字
[^a-z]:匹配范围;表示非小写字母(简单理解为非 a-z中的字母)
^:匹配开头;例如 :^[0-9]:表示以数字开头,并且只有一个数字,例如,字符串“1”匹配结果是true,字符串“12”匹配结果就是false
$:匹配结尾;例如:[0-9]$:表示以数字结尾,并且只有一个数字,同上
*:匹配0次或多次;例如:[0-9]*:表示匹配0次或多次数字
?:匹配0次或1次;例如:[0-9]?:表示匹配0次或一次数字
+:匹配1次或多次;例如:[0-9]+:表示匹配1次或多次数字
{n}:匹配确定的n次;例如:[0-9]{5};表示匹配5次数字
{n,m}:(n<=m)至少匹配n次,最多匹配m次;例如;[0-9]{1,2}:表示最少匹配一次数字,最多匹配2次数字

特殊字符

\d:表示一个十进制的数字 [0-9]
\D:表示非数字

\w:表示一个字符[0-9a-zA-Z_]
\W:表示除[0-9a-zA-Z_]之外的字符

\s:表示一个空白字符(空格,tab,换页符等)
\S:表示一个非空白字符
这些都是正则中能够表示一类字符的原子

常见写法

(1)匹配以某一个数字(字符)开头
^[1-9]:以1-9中的某一个数字开头,并且只有一个数字
(2)匹配固定格式开头
^(123):必须是123开头,并且这个串只有这三个数,例如,字符串“123”匹配结果是true,字符串“1234”匹配结果就是false,因为多了一个“4”,字符串“213”也是false,顺序不符合
(3)判断小数(转译字符相关java)
0\\.[1-9]:大于0小于1的小数,有且只有一个小数(这里重点关注哪个小数点的写法就行)

crontab表达式

详情参考:https://help.aliyun.com/document_detail/133509.html

基础语法

CRON 有如下两种语法格式:
秒 分 小时 日期 月份 星期 年
秒 分 小时 日期 月份 星期
一般都用下面这个(不带年的那个),“年”这个很少用到,可以暂时忽略

常用特殊字符

*:表示匹配域的任意值,在分这个域使用 *,即表示每分钟都会触发事件。
?:表示匹配域的任意值,但只能用在日期和星期两个域,因为这两个域会相互影响。示例:要在每月的 20 号触发调度,不管每个月的 20 号是星期几,则只能使用如下写法:0 0 0 20 * ?。其中,因为日期域已经指定了 20 号,最后一位星期域只能用 ?,不能使用 *。如果最后一位使用 *,则表示不管星期几都会触发,与日期域的 20 号相斥,此时表达式不正确。
-:表示起止范围,示例:在分这个域使用 5-20,表示从 5 分到 20 分钟每分钟触发一次。
/:表示起始时间开始触发,然后每隔固定时间触发一次,示例:在分这个域使用 5/20,表示从第5分钟开始触发,之后每 20 分钟触发一次,即 5、 25、45 等分别触发一次。

常用写法

*/5 * * * * ?:每隔 5 秒执行一次,等同于 0/5 * * * * ?
0 */1 * * * ?:每隔 1 分钟执行一次,等同于 0 0/1 * * * ?
0 0 2 1 * ?:每月 1 日的凌晨 2 点执行一次
0 15 10 ? * MON-FRI:周一到周五每天上午 10:15 执行作业
0 15 10 ? 6L 2002-2006:2002 年至 2006 年的每个月的最后一个星期五上午 10:15 执行作业
0 0 23 * * ?:每天 23 点执行一次
0 0 1 * * ?:每天凌晨 1 点执行一次
0 0 1 1 * ?:每月 1 日凌晨 1 点执行一次
0 0 23 L * ?:每月最后一天 23 点执行一次
0 0 1 ? * L:每周星期天凌晨 1 点执行一次
0 26,29,33 * * * ?:在 26 分、29 分、33 分执行一次
0 0 0,13,18,21 * * ?:每天的 0 点、13 点、18 点、21 点都执行一次
0 0 10,14,16 * * ?:每天上午 10 点,下午 2 点,4 点执行一次
0 0/30 9-17 * * ?:朝九晚五工作时间内每半小时执行一次
0 0 12 ? * WED:每个星期三中午 12 点执行一次
0 0 12 * * ?:每天中午 12 点触发
0 15 10 ? * *:每天上午 10:15 触发
0 15 10 * * ?:每天上午 10:15 触发
0 15 10 * * ? *:每天上午 10:15 触发
0 15 10 * * ? 2005:2005 年的每天上午 10:15 触发
0 * 14 * * ?:每天下午 2 点到 2:59 期间的每 1 分钟触发
0 0/5 14 * * ?:每天下午 2 点到 2:55 期间的每 5 分钟触发
0 0/5 14,18 * * ?:每天下午 2 点到 2:55 期间和下午 6 点到 6:55 期间的每 5 分钟触发
0 0-5 14 * * ?:每天下午 2 点到 2:05 期间的每 1 分钟触发
0 10,44 14 ? 3 WED:每年三月的星期三的下午 2:10 和 2:44 触发
0 15 10 ? * MON-FRI:周一至周五的上午 10:15 触发
0 15 10 15 * ?:每月 15 日上午 10:15 触发
0 15 10 L * ?:每月最后一日的上午 10:15 触发
0 15 10 ? * 6L:每月的最后一个星期五上午 10:15 触发
0 15 10 ? * 6L 2002-2005:2002 年至 2005 年的每月的最后一个星期五上午 10:15 触发
0 15 10 ? * 6#3:每月的第三个星期五上午 10:15 触发

常用小工具

(1)将电话号码的中间4位替换成*

public class Mobile {
    public static void main(String[] args) {
        String mobile = "13681467423";
        mobile = mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
        System.out.println(mobile);
    }
}

(2)姓名脱敏
脱敏规则: 只显示第一个汉字,比如李某某置换为李**, 李某置换为李*

private static String desensitizedName(String fullName){
        if (!Strings.isNullOrEmpty(name)) {
            String name = StringUtils.left(fullName, 1);
            return StringUtils.rightPad(name, StringUtils.length(fullName), "*");
        }
        return name;
    }

(3)身份证号脱敏
脱敏规则: 保留前六后三, 适用于15位和18位身份证号
方式一: 需要判断身份证号位数

private static String desensitizedIdNumber(String idNumber){
        if (!Strings.isNullOrEmpty(idNumber)) {
            if (idNumber.length() == 15){
                idNumber = idNumber.replaceAll("(\\w{6})\\w*(\\w{3})", "$1******$2");
            }
            if (idNumber.length() == 18){
                idNumber = idNumber.replaceAll("(\\w{6})\\w*(\\w{3})", "$1*********$2");
            }
            }
        return idNumber;
    }

(4)地址脱敏
脱敏规则: 从第4位开始隐藏,隐藏8位
因地址位数是不确定的,所以结尾长度为总长度减去 前面保留长度和隐藏长度之和 address.length()-11

private static String desensitizedAddress(String address){
        if (!Strings.isNullOrEmpty(address)) {
            return StringUtils.left(address, 3).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(address, address.length()-11), StringUtils.length(address), "*"), "***"));
        }
        return address;
    }

(5)日期相关
获取指定日期的23:59:59
示例:date为new date(),如果传入-1,获取的就是前一天的23:59:59;如果传入的是0,获取的是就是当天的23:59:59

	//new date(),-1
    public static Date getEndOfDate(Date date, int amount){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.add(Calendar.DAY_OF_MONTH, amount);
        return calendar.getTime();
    }

jdk自带的加解密工具

package com.jd.mcs.util;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.SecureRandom;

public class AesUtils {

    /**
     * 生成的key
     */
    private static Key key;

    /**
     * 生成密钥的字符串(自己随便写)
     */
    private static final String ENCRYPT_KEY = "test";


    /**
     * 加密
     * @param encryptionStr
     * @return
     */
    public static String encrypt(String encryptionStr) {
        try {
            // 加密
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, getKey());
            byte[] resultBytes = cipher.doFinal(encryptionStr.getBytes());
            //使用Base64将加密后的字节数组变成字符串
            return Base64.encodeBase64String(resultBytes);
        } catch (Exception e) {
            log.error("加密失败!", e);
            return null;
        }
    }


    /**
     * 解密
     * @param encryptionStr
     * @return
     */
    public static String decrypt(String encryptionStr) {
        try {
            // 解密
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, getKey());
            byte[] result = cipher.doFinal(Base64.decodeBase64(encryptionStr));
            return new String(result);
        } catch (Exception e) {
            log.error("解密失败!", e);
            return null;
        }
    }


    /**
     * 生成密钥
     * @return
     */
    public static Key getKey() {
        if (null != key) return key;
        synchronized (AesUtils.class) {
            if (null == key) {
                try {
                    // 生成KEY ,AES 要求密钥长度为 128
                    KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
                    SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
                    secureRandom.setSeed(ENCRYPT_KEY.getBytes());
                    keyGenerator.init(128, secureRandom);
                    SecretKey secretKey = keyGenerator.generateKey();
                    byte[] byteKey = secretKey.getEncoded();
                    // 转换KEY
                    key = new SecretKeySpec(byteKey, "AES");
                } catch (Exception e) {
                    log.error("生成密钥失败!", e);
                    e.printStackTrace();
                }
            }
        }
        return key;
    }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值