shz.core.RegexHelp Maven / Gradle / Ivy
package shz.core;
import shz.core.enums.Sex;
import shz.core.msg.ClientFailureMsg;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* (?d) Unix中的行
* (?i) 不区分大小写
* (?m) 多行
* (?s) 单行(dotall)
* (?u) Unicode
* (?x) 忽略空格和注释
* ()捕获分组,(?:)非捕获分组
* (?>)关闭回溯
* 前瞻,后顾(非捕获)
* (?=)正前瞻,(?!)反前瞻,(?<=)正后顾,(?
* 字符简写式
* \a 报警符,[\b] 退格字符,\b 单词边界,\B 非单词边界,\cx 控制字符,\d 数字字符,\D 非数字字符,\dxxx 字符的十进制值,\oxxx 字符的八进制值
* \s 空白符,\S 非空白符,\w 单词字符,\W 非单词字符,\0 空字符,\x xx 字符的十六进制值,\\u xxxx 字符的Unicode值
*
* posix字符组
* [[:ascii:]] ASCII字符(128个)
* [[:graph:]] 图形字符
* [[:print:]] 可打印字符
* [[:punct:]] 标点符号
* [[:space:]] 空格符号
*/
public final class RegexHelp {
private RegexHelp() {
throw new IllegalStateException();
}
public static final String CHAR = "^[\u0000-\uffff]$";
public static final Pattern P_CHAR = Pattern.compile(CHAR);
public static final String BOOLEAN = "^0|1|(?i:true|false)$";
public static final Pattern P_BOOLEAN = Pattern.compile(BOOLEAN);
public static final String UNSIGNED_BYTE = "^\\d|[1-9]\\d|1[01]\\d|12[0-7]$";
public static final Pattern P_UNSIGNED_BYTE = Pattern.compile(UNSIGNED_BYTE);
public static final String BYTE = "^0|-128|-?(?:[1-9]|[1-9]\\d|1[01]\\d|12[0-7])$";
public static final Pattern P_BYTE = Pattern.compile(BYTE);
public static final String UNSIGNED_DIGITAL = "^0|0\\.\\d+|[1-9]\\d*(?:\\.\\d+)?$";
public static final Pattern P_UNSIGNED_DIGITAL = Pattern.compile(UNSIGNED_DIGITAL);
public static final String DIGITAL = "^0|-?(?:0\\.\\d+|[1-9]\\d*(?:\\.\\d+)?)$";
public static final Pattern P_DIGITAL = Pattern.compile(DIGITAL);
public static final String PHONE = "^(?:13\\d|14[014-9]|15[0-35-9]|16[2567]|17[0-8]|18\\d|19[0-35-9])\\d{8}$";
public static final Pattern P_PHONE = Pattern.compile(PHONE);
public static final String CH_PHONE = "^\\d{3}-\\d{8}|\\d{4}-\\d{7}$";
public static final Pattern P_CH_PHONE = Pattern.compile(CH_PHONE);
public static final String EMAIL = "^\\w+@\\w+(?:\\.\\w+)+$";
public static final Pattern P_EMAIL = Pattern.compile(EMAIL);
public static final String IP = "^(?:(2(?:5[0-5]|[0-4]\\d))|1?\\d{1,2})(?:\\.(?:(2(?:5[0-5]|[0-4]\\d))|1?\\d{1,2})){3}$";
public static final Pattern P_IP = Pattern.compile(IP);
public static final String DOMAIN = "(?:^[a-zA-Z\\d](?:[a-zA-Z\\d-]{0,61}[a-zA-Z\\d])?\\.)+[a-zA-Z]{2,6}$";
public static final Pattern P_DOMAIN = Pattern.compile(DOMAIN);
public static final String URL = "^(?:(?:https?|ftp|file)://)?(?:[a-zA-Z\\d](?:[a-zA-Z\\d-]{0,61}[a-zA-Z\\d])?\\.)+[a-zA-Z]{2,6}(?::[1-5]\\d{1,4})?(?:/[\\w.@-_]+)*$";
public static final Pattern P_URL = Pattern.compile(URL);
public static final String HTML_TAG = "^<(?:[a-z\\d][^>]*/|([a-z\\d]\\w*+)[^>]*>.*?\\1)>$";
public static final Pattern P_HTML_TAG = Pattern.compile(HTML_TAG, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
public static final String CH_POSTAL_CODE = "^[1-9]\\d{5}(?!\\d)$";
public static final Pattern P_CH_POSTAL_CODE = Pattern.compile(CH_POSTAL_CODE);
public static final String QQ = "^[1-9]\\d{4,10}$";
public static final Pattern P_QQ = Pattern.compile(QQ);
public static final String NAME_CH = "^[\u4e00-\u9fa5]{2,4}$";
public static final Pattern P_NAME_CH = Pattern.compile(NAME_CH);
public static final String NAME_CH_MINORITY = "^[\u4e00-\u9fa5]+(?:[·•.][\u4e00-\u9fa5]+)*$";
public static final Pattern P_NAME_CH_MINORITY = Pattern.compile(NAME_CH_MINORITY);
public static final String NAME_EN = "^[a-zA-Z\\s]+(?:[·•.][a-zA-Z]+)*$";
public static final Pattern P_NAME_EN = Pattern.compile(NAME_EN);
public static final String LOGIN_NAME = "^[a-zA-Z\\d]{3,20}$";
public static final Pattern P_LOGIN_NAME = Pattern.compile(LOGIN_NAME);
public static final String PWD = "^[a-zA-Z\\d!\"#$%&'()*+,-./:;<=>?@\\[\\\\\\]^_`{|}~]{4,16}$";
public static final Pattern P_PWD = Pattern.compile(PWD);
public static final String NO = "^[\\da-zA-Z]{1,64}$";
public static final Pattern P_NO = Pattern.compile(NO);
public static final String MIDDLE_CH = "^[\u4e00-\u9fa5]{1,64}$";
public static final Pattern P_MIDDLE_CH = Pattern.compile(MIDDLE_CH);
public static final String CHAR_255 = "^[\u0000-\uffff]{0,255}$";
public static final Pattern P_CHAR_255 = Pattern.compile(CHAR_255);
/**
* @param flags 正则表达式中出现了^或者$, 默认只会匹配第一行. 设置了Pattern.MULTILINE模式,会匹配所有行
* 默认情况下, 正则表达式中点(.)不会匹配换行符, 设置了Pattern.DOTALL模式, 才会匹配所有字符包括换行符
*/
public static String find(String s, int flags, String regex, int group) {
if (s == null || regex == null) return s;
Matcher matcher = Pattern.compile(regex, flags).matcher(s);
return matcher.find() ? matcher.group(group) : null;
}
public static String find(String s, String regex) {
return find(s, 0, regex, 0);
}
public static String find(String s, Pattern pattern, int group) {
if (s == null || pattern == null) return s;
Matcher matcher = pattern.matcher(s);
return matcher.find() ? matcher.group(group) : null;
}
public static String find(String s, Pattern pattern) {
return find(s, pattern, 0);
}
public static String find(String s, boolean all, int flags, String... regexes) {
if (s == null || regexes.length == 0) return s;
String result = find(s, flags, regexes[0], 0);
if (regexes.length == 1) return result;
if (result == null) {
if (regexes[0] != null) return null;
result = s;
}
int i = 1;
for (; i < regexes.length; ++i) {
if (regexes[i] == null) continue;
String find = find(result, flags, regexes[i], 0);
if (find != null) {
result = find;
continue;
}
result = all ? null : result;
break;
}
return result;
}
public static String find(String s, boolean all, String... regexes) {
return find(s, all, 0, regexes);
}
public static String find(String s, String... regexes) {
return find(s, true, 0, regexes);
}
public static String find(String s, boolean all, Pattern... patterns) {
if (s == null || patterns.length == 0) return s;
String result = find(s, patterns[0], 0);
if (patterns.length == 1) return result;
if (result == null) {
if (patterns[0] != null) return null;
result = s;
}
int i = 1;
for (; i < patterns.length; ++i) {
if (patterns[i] == null) continue;
String find = find(result, patterns[i], 0);
if (find != null) {
result = find;
continue;
}
result = all ? null : result;
break;
}
return result;
}
public static String find(String s, Pattern... patterns) {
return find(s, true, patterns);
}
public static boolean isMatch(String s, String regex) {
return s != null && regex != null && Pattern.compile(regex).matcher(s).matches();
}
public static boolean nonMatch(String s, String regex) {
return !isMatch(s, regex);
}
public static boolean isAnyMatch(String s, String regex1, String regex2) {
if (s == null) return false;
return (regex1 != null && Pattern.compile(regex1).matcher(s).matches()) || (regex2 != null && Pattern.compile(regex2).matcher(s).matches());
}
public static boolean nonAnyMatch(String s, String regex1, String regex2) {
return !isAnyMatch(s, regex1, regex2);
}
public static boolean isAnyMatch(String s, String... regexes) {
if (s == null) return false;
for (String regex : regexes) if (regex != null && Pattern.compile(regex).matcher(s).matches()) return true;
return false;
}
public static boolean nonAnyMatch(String s, String... regexes) {
return !isAnyMatch(s, regexes);
}
public static boolean isAllMatch(String s, String regex1, String regex2) {
if (s == null || regex1 == null || regex2 == null) return false;
return Pattern.compile(regex1).matcher(s).matches() && Pattern.compile(regex2).matcher(s).matches();
}
public static boolean nonAllMatch(String s, String regex1, String regex2) {
return !isAllMatch(s, regex1, regex2);
}
public static boolean isAllMatch(String s, String... regexes) {
if (s == null) return false;
for (String regex : regexes) if (regex == null || !Pattern.compile(regex).matcher(s).matches()) return false;
return true;
}
public static boolean nonAllMatch(String s, String... regexes) {
return !isAllMatch(s, regexes);
}
public static boolean isMatch(String s, Pattern pattern) {
return s != null && pattern != null && pattern.matcher(s).matches();
}
public static boolean nonMatch(String s, Pattern pattern) {
return !isMatch(s, pattern);
}
public static boolean isAnyMatch(String s, Pattern pattern1, Pattern pattern2) {
if (s == null) return false;
return (pattern1 != null && pattern1.matcher(s).matches()) || (pattern2 != null && pattern2.matcher(s).matches());
}
public static boolean nonAnyMatch(String s, Pattern pattern1, Pattern pattern2) {
return !isAnyMatch(s, pattern1, pattern2);
}
public static boolean isAnyMatch(String s, Pattern... patterns) {
if (s == null) return false;
for (Pattern pattern : patterns) if (pattern != null && pattern.matcher(s).matches()) return true;
return false;
}
public static boolean nonAnyMatch(String s, Pattern... patterns) {
return !isAnyMatch(s, patterns);
}
public static boolean isAllMatch(String s, Pattern pattern1, Pattern pattern2) {
if (s == null || pattern1 == null || pattern2 == null) return false;
return pattern1.matcher(s).matches() && pattern2.matcher(s).matches();
}
public static boolean nonAllMatch(String s, Pattern pattern1, Pattern pattern2) {
return !isAllMatch(s, pattern1, pattern2);
}
public static boolean isAllMatch(String s, Pattern... patterns) {
if (s == null) return false;
for (Pattern pattern : patterns) if (pattern == null || !pattern.matcher(s).matches()) return false;
return true;
}
public static boolean nonAllMatch(String s, Pattern... patterns) {
return !isAllMatch(s, patterns);
}
/**
* 替换匹配正则
*/
public static String replace(String s, Pattern pattern, Function func) {
Matcher matcher = pattern.matcher(s);
if (!matcher.find()) return s;
matcher.reset();
StringBuilder sb = new StringBuilder();
int start = 0, end;
while (matcher.find()) {
end = matcher.start();
if (end > start) sb.append(s, start, end);
if (func != null) {
String rs = func.apply(matcher);
if (NullHelp.nonEmpty(rs)) sb.append(rs);
}
start = matcher.end();
}
if (start < s.length()) sb.append(s, start, s.length());
return sb.toString();
}
public static String replace(String s, int flags, String regex, Function func) {
return replace(s, Pattern.compile(regex, flags), func);
}
public static String replace(String s, String regex, Function func) {
return replace(s, 0, regex, func);
}
public static String replace(String s, Pattern pattern, String str) {
return replace(s, pattern, matcher -> str);
}
public static String replace(String s, int flags, String regex, String str) {
return replace(s, Pattern.compile(regex, flags), str);
}
public static String replace(String s, String regex, String str) {
return replace(s, 0, regex, str);
}
/**
* 移除匹配正则
*/
public static String strip(String s, Pattern pattern) {
return replace(s, pattern, (Function) null);
}
public static String strip(String s, int flags, String regex) {
return strip(s, Pattern.compile(regex, flags));
}
public static String strip(String s, String regex) {
return strip(s, 0, regex);
}
/**
* 消费匹配正则
*/
public static void consumer(String s, Pattern pattern, Consumer strConsumer, Consumer matcherConsumer) {
Matcher matcher = pattern.matcher(s);
int start = 0, end;
while (matcher.find()) {
end = matcher.start();
if (end > start) strConsumer.accept(s.substring(start, end));
matcherConsumer.accept(matcher);
start = matcher.end();
}
if (start < s.length()) strConsumer.accept(s.substring(start));
}
public static void consumer(String s, int flags, String regex, Consumer strConsumer, Consumer matcherConsumer) {
consumer(s, Pattern.compile(regex, flags), strConsumer, matcherConsumer);
}
public static void consumer(String s, String regex, Consumer strConsumer, Consumer matcherConsumer) {
consumer(s, 0, regex, strConsumer, matcherConsumer);
}
public static boolean isBirthday(String s) {
try {
LocalDateTime ldt = FieldSetter.cast(s, LocalDateTime.class);
if (ldt == null) return false;
return ldt.isBefore(LocalDateTime.now());
} catch (Exception e) {
return false;
}
}
private static final Map ID_R_C = ToMap.get(35)
.put("11", "北京").put("12", "天津").put("13", "河北").put("14", "山西")
.put("15", "内蒙古").put("21", "辽宁").put("22", "吉林").put("23", "黑龙江")
.put("31", "上海").put("32", "江苏").put("33", "浙江").put("34", "安徽")
.put("35", "福建").put("36", "江西").put("37", "山东").put("41", "河南")
.put("42", "湖北").put("43", "湖南").put("44", "广东").put("45", "广西")
.put("46", "海南").put("50", "重庆").put("51", "四川").put("52", "贵州")
.put("53", "云南").put("54", "西藏").put("61", "陕西").put("62", "甘肃")
.put("63", "青海").put("64", "宁夏").put("65", "新疆").put("71", "台湾")
.put("81", "香港").put("82", "澳门").put("91", "国外").build();
private static final int[] ID_W = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
private static final int[] ID_M = {1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2};
public static boolean isIdentity(String s) {
if (s == null) return false;
if (s.length() == 15) return isBirthday("19" + s.substring(6, 12));
if (s.length() != 18) return false;
if (!ID_R_C.containsKey(s.substring(0, 2))) return false;
int[] c_i = new int[17];
for (int i = 0; i < c_i.length; ++i) c_i[i] = s.charAt(i) - '0';
int sum = 0;
for (int i = 0; i < 17; ++i) sum += c_i[i] * ID_W[i];
char c = s.charAt(17);
return ID_M[sum % 11] == ((c == 'x' || c == 'X') ? 10 : c - '0');
}
/**
* 获取身份证号所在地区
*/
public static String getIdentityRegion(String identity) {
return ID_R_C.get(identity.substring(0, 2));
}
/**
* 获取身份证号出生日期
*/
public static String getIdentityBirthday(String identity) {
return identity.length() == 15 ? "19" + identity.substring(6, 12) : identity.substring(6, 14);
}
/**
* 获取身份证号年龄
*/
public static int getIdentityAge(String identity) {
return TimeHelp.between(TimeHelp.toLdt(getIdentityBirthday(identity)).toLocalDate(), LocalDate.now()).getYears();
}
/**
* 获取身份证号性别
*/
public static Sex getIdentitySex(String identity) {
return ((identity.charAt(16) - '0') & 1) == 0 ? Sex.F : Sex.M;
}
private static final Pattern P_LUNE_CHECK = Pattern.compile("^\\d{8,19}$");
/**
* 判断是否卡号
*/
public static boolean luneCheck(String s) {
if (s == null || !P_LUNE_CHECK.matcher(s).matches()) return false;
return luneCompute(s.substring(0, s.length() - 1)) == s.charAt(s.length() - 1) - '0';
}
private static final Pattern P_LUNE_COMPUTE = Pattern.compile("^\\d{7,18}$");
/**
* 计算卡号校验位
*/
public static int luneCompute(String s) {
ClientFailureMsg.requireNon(s == null || !P_LUNE_COMPUTE.matcher(s).matches(), "非法卡号");
int mod = luneSum(s) % 10;
return mod == 0 ? 0 : 10 - mod;
}
private static int luneSum(String s) {
int sum = 0;
for (int i = s.length() - 1, j = 0; i > -1; --i, ++j) {
int n = s.charAt(i) - '0';
if ((j & 1) == 0) {
n <<= 1;
n = n / 10 + n % 10;
}
sum += n;
}
return sum;
}
}