From cba2537db778efec0200bd6f200b0249eb75caac Mon Sep 17 00:00:00 2001 From: 21001 <2100166581@qq.com> Date: Sat, 13 Jan 2024 10:03:11 +0800 Subject: [PATCH 1/2] =?UTF-8?q?add=20=E6=AD=A3=E5=88=99=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=B1=BB=EF=BC=8C=E6=96=B0=E5=A2=9E=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?UTF-8?q?=E6=8F=90=E5=8F=96=EF=BC=8C=E5=AD=97=E7=AC=A6=E4=B8=B2=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/constant/RegexConstants.java | 85 +++++++++++++++++++ .../org/dromara/common/core/utils/ReUtil.java | 85 ++++++++++++++++++- .../system/domain/bo/SysDictTypeBo.java | 12 +-- 3 files changed, 173 insertions(+), 9 deletions(-) create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/RegexConstants.java diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/RegexConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/RegexConstants.java new file mode 100644 index 00000000..e4e7eb09 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/RegexConstants.java @@ -0,0 +1,85 @@ +package org.dromara.common.core.constant; + +/** + * 正则表达式 + * + * @author Feng + */ +public interface RegexConstants { + + /** + * 中文字符正则表达式 + */ + public static final String CHINESE_REGEX = "[\\u4e00-\\u9fa5]+"; + + /** + * 姓名(2-4个中文字符正则) + */ + public static final String NAME_REGEX = "^[\u4e00-\u9fa5]{2,4}$"; + + /** + * 匹配中国大陆手机号码 + */ + public static final String PHONE_NUMBER_REGEX = "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$"; + + /** + * 座机号码 + */ + public static final String LANDLINE_REGEX = "^(0\\d{2,3})-?(\\d{7,8})$"; + + /** + * 电子邮箱 + */ + public static final String EMAIL_REGEX = "^[\\w+&*-]+(?:\\.[\\w+&*-]+)*@(?:[\\w+&*-]+\\.)+[a-zA-Z]{2,7}$"; + + /** + * 身份证号码(普通校验) + */ + public static final String ID_CARD_REGEX_GENERAL = "(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)"; + + /** + * 身份证号码(精准校验 - 18位) + */ + public static final String ID_CARD_REGEX_ACCURATE_18 = "^[1-9]\\d{5}(19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$"; + + /** + * 身份证号码(15位) + */ + public static final String ID_CARD_REGEX_ACCURATE_15 = "^[1-9]\\d{5}\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{2}[0-9Xx]$"; + + /** + * 身份证号码(后6位) + */ + public static final String ID_CARD_REGEX_LAST_6 = "^(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$"; + + /** + * QQ号码 + */ + public static final String QQ_NUMBER_REGEX = "^[1-9][0-9]\\d{4,9}$"; + + /** + * 邮政编码 + */ + public static final String POSTAL_CODE_REGEX = "^[1-9]\\d{5}$"; + + /** + * 注册账号 + */ + public static final String ACCOUNT_REGEX = "^[a-zA-Z][a-zA-Z0-9_]{4,15}$"; + + /** + * 密码:包含至少8个字符,包括大写字母、小写字母、数字和特殊字符 + */ + public static final String PASSWORD_REGEX = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$"; + + /** + * 通用状态(0表示正常,1表示停用) + */ + public static final String STATUS_REGEX = "^[01]$"; + + /** + * 字典类型必须以字母开头,且只能为(小写字母,数字,下滑线) + */ + public static final String DICTIONARY_TYPE_REGEX = "^[a-z][a-z0-9_]*$"; + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ReUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ReUtil.java index 2de7f4f8..c9b673ab 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ReUtil.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ReUtil.java @@ -2,6 +2,8 @@ package org.dromara.common.core.utils; import cn.hutool.core.convert.Convert; +import org.dromara.common.core.constant.RegexConstants; +import org.dromara.common.core.exception.ServiceException; import java.util.Arrays; import java.util.Collection; @@ -10,15 +12,92 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * 正则工具类 + * + * @author Feng + */ public class ReUtil { public final static Pattern GROUP_VAR = Pattern.compile("\\$(\\d+)"); /** * 正则中需要被转义的关键字 */ - public final static Set RE_KEYS = new HashSet<>( - Arrays.asList('$', '(', ')', '*', '+', '.', '[', ']', '?', '\\', '^', '{', '}', '|')); - ; + public final static Set RE_KEYS = new HashSet<>(Arrays.asList('$', '(', ')', '*', '+', '.', '[', ']', '?', '\\', '^', '{', '}', '|')); + + /** + * 判断字符串是否匹配指定的正则表达式 + * + * @param input 要检查的字符串 + * @param regex 用于匹配的正则表达式,可以使用 {@link RegexConstants} 中定义的常量 + * @return 如果字符串与正则表达式匹配,返回 true;否则返回 false + * @throws IllegalArgumentException 如果输入字符串或正则表达式为 null + */ + public static boolean isValid(String input, String regex) { + // 检查输入参数是否为null,如果是则抛出IllegalArgumentException + if (StringUtils.isEmpty(input) || StringUtils.isEmpty(regex)) { + throw new ServiceException("输入和正则表达式不得为空"); + } + // 编译正则表达式 + Pattern pattern = Pattern.compile(regex); + // 创建匹配器对象,并将输入字符串与正则表达式进行匹配 + Matcher matcher = pattern.matcher(input); + // 返回匹配结果 + return matcher.matches(); + } + + /** + * 从输入字符串中提取匹配的部分 + * + * @param input 要提取的输入字符串 + * @param regex 用于匹配的正则表达式,可以使用 {@link RegexConstants} 中定义的常量 + * @return 如果找到匹配的部分,则返回匹配的部分,否则返回原始输入字符串 + */ + public static String extractFromString(String input, String regex) { + // 检查输入参数是否为null,如果是则抛出IllegalArgumentException + if (StringUtils.isEmpty(input) || StringUtils.isEmpty(regex)) { + throw new ServiceException("输入和正则表达式不得为空"); + } + // 编译正则表达式 + Pattern pattern = Pattern.compile(regex); + // 创建匹配器 + Matcher matcher = pattern.matcher(input); + // 查找匹配 + if (matcher.find()) { + // 获取匹配的部分 + return matcher.group(1); + } else { + // 如果没有匹配,返回原始字符串 + return input; + } + } + + /** + * 从输入字符串中提取匹配的部分,如果没有匹配则返回默认值 + * + * @param input 要提取的输入字符串 + * @param regex 用于匹配的正则表达式,可以使用 {@link RegexConstants} 中定义的常量 + * @param defaultInput 如果没有匹配时返回的默认值 + * @return 如果找到匹配的部分,则返回匹配的部分,否则返回默认值 + */ + public static String extractFromString(String input, String regex, String defaultInput) { + // 检查输入参数是否为null,如果是则抛出IllegalArgumentException + if (StringUtils.isEmpty(input) || StringUtils.isEmpty(regex)) { + throw new ServiceException("输入和正则表达式不得为空"); + } + // 编译正则表达式 + Pattern pattern = Pattern.compile(regex); + // 创建匹配器 + Matcher matcher = pattern.matcher(input); + // 查找匹配 + if (matcher.find()) { + // 获取匹配的部分 + return matcher.group(1); + } else { + // 如果没有匹配,返回默认值 + return defaultInput; + } + } /** * 正则替换指定值
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictTypeBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictTypeBo.java index e4b15145..e3336936 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictTypeBo.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictTypeBo.java @@ -1,18 +1,18 @@ package org.dromara.system.domain.bo; import io.github.linpeilie.annotations.AutoMapper; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import lombok.Data; import lombok.EqualsAndHashCode; +import org.dromara.common.core.constant.RegexConstants; import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.EditGroup; import org.dromara.common.mybatis.core.domain.BaseEntity; import org.dromara.system.domain.SysDictType; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Pattern; -import jakarta.validation.constraints.Size; - /** * 字典类型业务对象 sys_dict_type * @@ -42,7 +42,7 @@ public class SysDictTypeBo extends BaseEntity { */ @NotBlank(message = "字典类型不能为空", groups = { AddGroup.class, EditGroup.class }) @Size(min = 0, max = 100, message = "字典类型类型长度不能超过{max}个字符") - @Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)") + @Pattern(regexp = RegexConstants.DICTIONARY_TYPE_REGEX, message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)") private String dictType; /** From 79b583b5ab80fbcede8e184604cb9d5b19f88107 Mon Sep 17 00:00:00 2001 From: 21001 <2100166581@qq.com> Date: Sat, 13 Jan 2024 12:18:11 +0800 Subject: [PATCH 2/2] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=E6=AD=A3?= =?UTF-8?q?=E5=88=99=E7=BC=96=E8=AF=91=EF=BC=8C=E6=94=BE=E5=85=A5=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E6=B1=A0=E5=B7=A5=E5=8E=82=EF=BC=8C=E4=B8=8D=E7=94=A8?= =?UTF-8?q?=E6=AF=8F=E6=AC=A1=E8=B0=83=E7=94=A8=E9=83=BD=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E4=B8=80=E6=AC=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/constant/RegexConstants.java | 64 ++--- .../core/factory/RegexPatternPoolFactory.java | 52 ++++ .../org/dromara/common/core/utils/ReUtil.java | 227 ------------------ .../common/core/utils/regex/RegexUtils.java | 30 +++ .../core/utils/regex/RegexValidator.java | 105 ++++++++ .../system/domain/bo/SysDictTypeBo.java | 2 +- 6 files changed, 202 insertions(+), 278 deletions(-) create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/factory/RegexPatternPoolFactory.java delete mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ReUtil.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/regex/RegexUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/regex/RegexValidator.java diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/RegexConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/RegexConstants.java index e4e7eb09..b13c0571 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/RegexConstants.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/RegexConstants.java @@ -1,85 +1,49 @@ package org.dromara.common.core.constant; +import cn.hutool.core.lang.RegexPool; + /** - * 正则表达式 + * 常用正则表达式字符串 + *

+ * 常用正则表达式集合,更多正则见: https://any86.github.io/any-rule/ * * @author Feng */ -public interface RegexConstants { - - /** - * 中文字符正则表达式 - */ - public static final String CHINESE_REGEX = "[\\u4e00-\\u9fa5]+"; - - /** - * 姓名(2-4个中文字符正则) - */ - public static final String NAME_REGEX = "^[\u4e00-\u9fa5]{2,4}$"; +public interface RegexConstants extends RegexPool { /** - * 匹配中国大陆手机号码 - */ - public static final String PHONE_NUMBER_REGEX = "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$"; - - /** - * 座机号码 - */ - public static final String LANDLINE_REGEX = "^(0\\d{2,3})-?(\\d{7,8})$"; - - /** - * 电子邮箱 - */ - public static final String EMAIL_REGEX = "^[\\w+&*-]+(?:\\.[\\w+&*-]+)*@(?:[\\w+&*-]+\\.)+[a-zA-Z]{2,7}$"; - - /** - * 身份证号码(普通校验) - */ - public static final String ID_CARD_REGEX_GENERAL = "(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)"; - - /** - * 身份证号码(精准校验 - 18位) - */ - public static final String ID_CARD_REGEX_ACCURATE_18 = "^[1-9]\\d{5}(19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$"; - - /** - * 身份证号码(15位) + * 字典类型必须以字母开头,且只能为(小写字母,数字,下滑线) */ - public static final String ID_CARD_REGEX_ACCURATE_15 = "^[1-9]\\d{5}\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{2}[0-9Xx]$"; + public static final String DICTIONARY_TYPE = "^[a-z][a-z0-9_]*$"; /** * 身份证号码(后6位) */ - public static final String ID_CARD_REGEX_LAST_6 = "^(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$"; + public static final String ID_CARD_LAST_6 = "^(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$"; /** * QQ号码 */ - public static final String QQ_NUMBER_REGEX = "^[1-9][0-9]\\d{4,9}$"; + public static final String QQ_NUMBER = "^[1-9][0-9]\\d{4,9}$"; /** * 邮政编码 */ - public static final String POSTAL_CODE_REGEX = "^[1-9]\\d{5}$"; + public static final String POSTAL_CODE = "^[1-9]\\d{5}$"; /** * 注册账号 */ - public static final String ACCOUNT_REGEX = "^[a-zA-Z][a-zA-Z0-9_]{4,15}$"; + public static final String ACCOUNT = "^[a-zA-Z][a-zA-Z0-9_]{4,15}$"; /** * 密码:包含至少8个字符,包括大写字母、小写字母、数字和特殊字符 */ - public static final String PASSWORD_REGEX = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$"; + public static final String PASSWORD = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$"; /** * 通用状态(0表示正常,1表示停用) */ - public static final String STATUS_REGEX = "^[01]$"; - - /** - * 字典类型必须以字母开头,且只能为(小写字母,数字,下滑线) - */ - public static final String DICTIONARY_TYPE_REGEX = "^[a-z][a-z0-9_]*$"; + public static final String STATUS = "^[01]$"; } diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/factory/RegexPatternPoolFactory.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/factory/RegexPatternPoolFactory.java new file mode 100644 index 00000000..fd907d2c --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/factory/RegexPatternPoolFactory.java @@ -0,0 +1,52 @@ +package org.dromara.common.core.factory; + +import cn.hutool.core.lang.PatternPool; +import org.dromara.common.core.constant.RegexConstants; + +import java.util.regex.Pattern; + +/** + * 正则表达式模式池工厂 + *

初始化的时候将正则表达式加入缓存池当中

+ *

提高正则表达式的性能,避免重复编译相同的正则表达式

+ * + * @author 21001 + */ +public class RegexPatternPoolFactory extends PatternPool { + + /** + * 字典类型必须以字母开头,且只能为(小写字母,数字,下滑线) + */ + public static final Pattern DICTIONARY_TYPE = get(RegexConstants.DICTIONARY_TYPE); + + /** + * 身份证号码(后6位) + */ + public static final Pattern ID_CARD_LAST_6 = get(RegexConstants.ID_CARD_LAST_6); + + /** + * QQ号码 + */ + public static final Pattern QQ_NUMBER = get(RegexConstants.QQ_NUMBER); + + /** + * 邮政编码 + */ + public static final Pattern POSTAL_CODE = get(RegexConstants.POSTAL_CODE); + + /** + * 注册账号 + */ + public static final Pattern ACCOUNT = get(RegexConstants.ACCOUNT); + + /** + * 密码:包含至少8个字符,包括大写字母、小写字母、数字和特殊字符 + */ + public static final Pattern PASSWORD = get(RegexConstants.PASSWORD); + + /** + * 通用状态(0表示正常,1表示停用) + */ + public static final Pattern STATUS = get(RegexConstants.STATUS); + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ReUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ReUtil.java deleted file mode 100644 index c9b673ab..00000000 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ReUtil.java +++ /dev/null @@ -1,227 +0,0 @@ -package org.dromara.common.core.utils; - - -import cn.hutool.core.convert.Convert; -import org.dromara.common.core.constant.RegexConstants; -import org.dromara.common.core.exception.ServiceException; - -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * 正则工具类 - * - * @author Feng - */ -public class ReUtil { - public final static Pattern GROUP_VAR = Pattern.compile("\\$(\\d+)"); - - /** - * 正则中需要被转义的关键字 - */ - public final static Set RE_KEYS = new HashSet<>(Arrays.asList('$', '(', ')', '*', '+', '.', '[', ']', '?', '\\', '^', '{', '}', '|')); - - /** - * 判断字符串是否匹配指定的正则表达式 - * - * @param input 要检查的字符串 - * @param regex 用于匹配的正则表达式,可以使用 {@link RegexConstants} 中定义的常量 - * @return 如果字符串与正则表达式匹配,返回 true;否则返回 false - * @throws IllegalArgumentException 如果输入字符串或正则表达式为 null - */ - public static boolean isValid(String input, String regex) { - // 检查输入参数是否为null,如果是则抛出IllegalArgumentException - if (StringUtils.isEmpty(input) || StringUtils.isEmpty(regex)) { - throw new ServiceException("输入和正则表达式不得为空"); - } - // 编译正则表达式 - Pattern pattern = Pattern.compile(regex); - // 创建匹配器对象,并将输入字符串与正则表达式进行匹配 - Matcher matcher = pattern.matcher(input); - // 返回匹配结果 - return matcher.matches(); - } - - /** - * 从输入字符串中提取匹配的部分 - * - * @param input 要提取的输入字符串 - * @param regex 用于匹配的正则表达式,可以使用 {@link RegexConstants} 中定义的常量 - * @return 如果找到匹配的部分,则返回匹配的部分,否则返回原始输入字符串 - */ - public static String extractFromString(String input, String regex) { - // 检查输入参数是否为null,如果是则抛出IllegalArgumentException - if (StringUtils.isEmpty(input) || StringUtils.isEmpty(regex)) { - throw new ServiceException("输入和正则表达式不得为空"); - } - // 编译正则表达式 - Pattern pattern = Pattern.compile(regex); - // 创建匹配器 - Matcher matcher = pattern.matcher(input); - // 查找匹配 - if (matcher.find()) { - // 获取匹配的部分 - return matcher.group(1); - } else { - // 如果没有匹配,返回原始字符串 - return input; - } - } - - /** - * 从输入字符串中提取匹配的部分,如果没有匹配则返回默认值 - * - * @param input 要提取的输入字符串 - * @param regex 用于匹配的正则表达式,可以使用 {@link RegexConstants} 中定义的常量 - * @param defaultInput 如果没有匹配时返回的默认值 - * @return 如果找到匹配的部分,则返回匹配的部分,否则返回默认值 - */ - public static String extractFromString(String input, String regex, String defaultInput) { - // 检查输入参数是否为null,如果是则抛出IllegalArgumentException - if (StringUtils.isEmpty(input) || StringUtils.isEmpty(regex)) { - throw new ServiceException("输入和正则表达式不得为空"); - } - // 编译正则表达式 - Pattern pattern = Pattern.compile(regex); - // 创建匹配器 - Matcher matcher = pattern.matcher(input); - // 查找匹配 - if (matcher.find()) { - // 获取匹配的部分 - return matcher.group(1); - } else { - // 如果没有匹配,返回默认值 - return defaultInput; - } - } - - /** - * 正则替换指定值
- * 通过正则查找到字符串,然后把匹配到的字符串加入到replacementTemplate中,$1表示分组1的字符串 - * - *

- * 例如:原字符串是:中文1234,我想把1234换成(1234),则可以: - * - *

-     * ReUtil.replaceAll("中文1234", "(\\d+)", "($1)"))
-     *
-     * 结果:中文(1234)
-     * 
- * - * @param content 文本 - * @param regex 正则 - * @param replacementTemplate 替换的文本模板,可以使用$1类似的变量提取正则匹配出的内容 - * @return 处理后的文本 - */ - public static String replaceAll(CharSequence content, String regex, String replacementTemplate) { - final Pattern pattern = Pattern.compile(regex, Pattern.DOTALL); - return replaceAll(content, pattern, replacementTemplate); - } - - /** - * 正则替换指定值
- * 通过正则查找到字符串,然后把匹配到的字符串加入到replacementTemplate中,$1表示分组1的字符串 - * - * @param content 文本 - * @param pattern {@link Pattern} - * @param replacementTemplate 替换的文本模板,可以使用$1类似的变量提取正则匹配出的内容 - * @return 处理后的文本 - * @since 3.0.4 - */ - public static String replaceAll(CharSequence content, Pattern pattern, String replacementTemplate) { - if (StringUtils.isEmpty(content)) { - return StringUtils.EMPTY; - } - - final Matcher matcher = pattern.matcher(content); - boolean result = matcher.find(); - if (result) { - final Set varNums = findAll(GROUP_VAR, replacementTemplate, 1, new HashSet<>()); - final StringBuffer sb = new StringBuffer(); - do { - String replacement = replacementTemplate; - for (String var : varNums) { - int group = Integer.parseInt(var); - replacement = replacement.replace("$" + var, matcher.group(group)); - } - matcher.appendReplacement(sb, escape(replacement)); - result = matcher.find(); - } - while (result); - matcher.appendTail(sb); - return sb.toString(); - } - return Convert.toStr(content); - } - - /** - * 取得内容中匹配的所有结果 - * - * @param 集合类型 - * @param pattern 编译后的正则模式 - * @param content 被查找的内容 - * @param group 正则的分组 - * @param collection 返回的集合类型 - * @return 结果集 - */ - public static > T findAll(Pattern pattern, CharSequence content, int group, - T collection) { - if (null == pattern || null == content) { - return null; - } - - if (null == collection) { - throw new NullPointerException("Null collection param provided!"); - } - - final Matcher matcher = pattern.matcher(content); - while (matcher.find()) { - collection.add(matcher.group(group)); - } - return collection; - } - - /** - * 转义字符,将正则的关键字转义 - * - * @param c 字符 - * @return 转义后的文本 - */ - public static String escape(char c) { - final StringBuilder builder = new StringBuilder(); - if (RE_KEYS.contains(c)) { - builder.append('\\'); - } - builder.append(c); - return builder.toString(); - } - - /** - * 转义字符串,将正则的关键字转义 - * - * @param content 文本 - * @return 转义后的文本 - */ - public static String escape(CharSequence content) { - if (StringUtils.isBlank(content)) { - return StringUtils.EMPTY; - } - - final StringBuilder builder = new StringBuilder(); - int len = content.length(); - char current; - for (int i = 0; i < len; i++) { - current = content.charAt(i); - if (RE_KEYS.contains(current)) { - builder.append('\\'); - } - builder.append(current); - } - return builder.toString(); - } - -} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/regex/RegexUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/regex/RegexUtils.java new file mode 100644 index 00000000..b8b12d43 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/regex/RegexUtils.java @@ -0,0 +1,30 @@ +package org.dromara.common.core.utils.regex; + + +import cn.hutool.core.util.ReUtil; +import org.dromara.common.core.constant.RegexConstants; + +/** + * 正则相关工具类 + * + * @author Feng + */ +public final class RegexUtils extends ReUtil { + + /** + * 从输入字符串中提取匹配的部分,如果没有匹配则返回默认值 + * + * @param input 要提取的输入字符串 + * @param regex 用于匹配的正则表达式,可以使用 {@link RegexConstants} 中定义的常量 + * @param defaultInput 如果没有匹配时返回的默认值 + * @return 如果找到匹配的部分,则返回匹配的部分,否则返回默认值 + */ + public static String extractFromString(String input, String regex, String defaultInput) { + try { + return ReUtil.get(regex, input, 1); + } catch (Exception e) { + return defaultInput; + } + } + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/regex/RegexValidator.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/regex/RegexValidator.java new file mode 100644 index 00000000..c0dda202 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/regex/RegexValidator.java @@ -0,0 +1,105 @@ +package org.dromara.common.core.utils.regex; + +import cn.hutool.core.exceptions.ValidateException; +import cn.hutool.core.lang.Validator; +import org.dromara.common.core.factory.RegexPatternPoolFactory; + +import java.util.regex.Pattern; + +/** + * 正则字段校验器 + * 主要验证字段非空、是否为满足指定格式等 + * + * @author Feng + */ +public class RegexValidator extends Validator { + + /** + * 字典类型必须以字母开头,且只能为(小写字母,数字,下滑线) + */ + public static final Pattern DICTIONARY_TYPE = RegexPatternPoolFactory.DICTIONARY_TYPE; + + /** + * 身份证号码(后6位) + */ + public static final Pattern ID_CARD_LAST_6 = RegexPatternPoolFactory.ID_CARD_LAST_6; + + /** + * QQ号码 + */ + public static final Pattern QQ_NUMBER = RegexPatternPoolFactory.QQ_NUMBER; + + /** + * 邮政编码 + */ + public static final Pattern POSTAL_CODE = RegexPatternPoolFactory.POSTAL_CODE; + + /** + * 注册账号 + */ + public static final Pattern ACCOUNT = RegexPatternPoolFactory.ACCOUNT; + + /** + * 密码:包含至少8个字符,包括大写字母、小写字母、数字和特殊字符 + */ + public static final Pattern PASSWORD = RegexPatternPoolFactory.PASSWORD; + + /** + * 通用状态(0表示正常,1表示停用) + */ + public static final Pattern STATUS = RegexPatternPoolFactory.STATUS; + + + /** + * 检查输入的账号是否匹配预定义的规则 + * + * @param value 要验证的账号 + * @return 如果账号符合规则,返回 true;否则,返回 false。 + */ + public static boolean isAccount(CharSequence value) { + return isMatchRegex(ACCOUNT, value); + } + + /** + * 验证输入的账号是否符合规则,如果不符合,则抛出 ValidateException 异常 + * + * @param value 要验证的账号 + * @param errorMsg 验证失败时抛出的异常消息 + * @param CharSequence 的子类型 + * @return 如果验证通过,返回输入的账号 + * @throws ValidateException 如果验证失败 + */ + public static T validateAccount(T value, String errorMsg) throws ValidateException { + if (!isAccount(value)) { + throw new ValidateException(errorMsg); + } + return value; + } + + /** + * 检查输入的状态是否匹配预定义的规则 + * + * @param value 要验证的状态 + * @return 如果状态符合规则,返回 true;否则,返回 false。 + */ + public static boolean isStatus(CharSequence value) { + return isMatchRegex(STATUS, value); + } + + /** + * 验证输入的状态是否符合规则,如果不符合,则抛出 ValidateException 异常 + * + * @param value 要验证的状态 + * @param errorMsg 验证失败时抛出的异常消息 + * @param CharSequence 的子类型 + * @return 如果验证通过,返回输入的状态 + * @throws ValidateException 如果验证失败 + */ + public static T validateStatus(T value, String errorMsg) throws ValidateException { + if (!isStatus(value)) { + throw new ValidateException(errorMsg); + } + return value; + } + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictTypeBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictTypeBo.java index e3336936..18a1979f 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictTypeBo.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDictTypeBo.java @@ -42,7 +42,7 @@ public class SysDictTypeBo extends BaseEntity { */ @NotBlank(message = "字典类型不能为空", groups = { AddGroup.class, EditGroup.class }) @Size(min = 0, max = 100, message = "字典类型类型长度不能超过{max}个字符") - @Pattern(regexp = RegexConstants.DICTIONARY_TYPE_REGEX, message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)") + @Pattern(regexp = RegexConstants.DICTIONARY_TYPE, message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)") private String dictType; /**