Files
estate/src/utils/Reg.ts
2026-07-30 17:59:32 +08:00

217 lines
6.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 验证身份证号码18位支持尾号x/X
* @param idCard 身份证号
* @return {boolean} true 符合 false 不符合
*/
export function validateIdCard(idCard: string): boolean {
// 18位身份证正则
const reg = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
return reg.test(idCard.trim());
}
/**
* 验证车牌号
* @param val 兼容新能源 + 普通车牌
* @return {boolean} true 符合 false 不符合
*/
export function isPlateNumber(val: string): boolean {
const reg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼][A-Z][A-HJ-NP-Z0-9]{4,5}[A-HJ-NP-Z0-9挂学警港澳]$/;
return reg.test(val);
}
/**
* 验证金钱
* @return {boolean} true 符合 false 不符合
* @param value
*/
export function isMoney(value: number): boolean {
const reg = /^(0|[1-9]\d*)(\.\d{1,2})?$/;
return reg.test(String(value).trim());
}
/**
* 验证姓名
* @param {string} val
* @return {boolean} true 符合 false 不符合
*/
export function isChineseName(val: string): boolean {
return /^[\u4e00-\u9fa5·]{2,16}$/.test(String(val).trim());
}
const reg = {
/** 金钱 */
money: /^(0|[1-9]\d*)(\.\d{1,2})?$/,
/** 身份证 */
idCard: /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/,
/** 车牌 */
PlateNumber: /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼][A-Z][A-HJ-NP-Z0-9]{4,5}[A-HJ-NP-Z0-9挂学警港澳]$/,
/** 姓名 */
ChineseName: /^[\u4e00-\u9fa5·]{2,16}$/,
/** 手机号 */
phone: /^1[3-9]\d{9}$/,
/** 邮箱 */
email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
/** QQ */
qq: /^[1-9]\d{4,11}$/,
/** 微信 */
wechat: /^[a-zA-Z][a-zA-Z0-9_-]{5,19}$/,
/** 护照 */
passport: /^[EG]\d{8}$/,
/** 港澳通行证 */
hongkongPassport: /^[CHMW]\d{8}$/
};
// 自动推导 TS 类型(最标准)
export type RegType = keyof typeof reg;
/**
* 验证姓名
* @param {string|number} value
* @param {string} regType
* @return {boolean} true 符合 false 不符合
*/
export function validator(value: string | number, regType: RegType): boolean {
return reg[regType].test(String(value));
}
/**
* 车牌验证工具类
* 支持传统燃油、新能源、军警、武警、使馆、临时、港澳、挂车等全量车牌
*/
export class LicensePlateValidator {
/**
* 省份简称正则片段
*/
private static readonly PROVINCE = '[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]';
/**
* 验证传统燃油车牌 (蓝牌/黄牌)
* 格式: 省份 + 字母 + 5位字符 (数字或字母排除I,O)
* 示例: 京A·12345, 粤B·88888
* 总长7位
*/
static isTraditionalPlate(plate: string): boolean {
const reg = new RegExp(`^${this.PROVINCE}[A-HJ-NP-Z][A-HJ-NP-Z0-9]{5}$`);
if (!reg.test(plate.toUpperCase())) return false;
return true;
}
/**
* 验证新能源车牌 (绿牌)
* 规则:除了标识位 D/F 外,其余序号位必须为数字 (0-9)
* 小型: 省份 + 字母 + D/F + 5位数字 或 省份 + 字母 + 5位数字 + D/F
* 大型: 省份 + 字母 + 5位数字 + D/F
* 总长8位
*/
static isNewEnergyPlate(plate: string): boolean {
// 修正非D/F位仅限数字
// 1. [省份][A-HJ-NP-Z][D-F][0-9]{5} (D/F在序号第1位后跟5位数字)
// 2. [省份][A-HJ-NP-Z][0-9]{5}[D-F] (D/F在序号最后1位前跟5位数字)
const reg = new RegExp(`^${this.PROVINCE}[A-HJ-NP-Z](?:[D-F][0-9]{5}|[0-9]{5}[D-F])$`);
return reg.test(plate.toUpperCase());
}
/**
* 验证警车车牌
* 格式: 省份 + 字母 + 4位数字 + 警
* 总长7位
*/
static isPolicePlate(plate: string): boolean {
const reg = new RegExp(`^${this.PROVINCE}[A-HJ-NP-Z][0-9]{4}警$`);
return reg.test(plate.toUpperCase());
}
/**
* 验证教练车牌
* 格式: 省份 + 字母 + 4位数字 + 学
* 总长7位
*/
static isCoachPlate(plate: string): boolean {
const reg = new RegExp(`^${this.PROVINCE}[A-HJ-NP-Z][0-9]{4}学$`);
return reg.test(plate.toUpperCase());
}
/**
* 验证挂车车牌
* 格式: 省份 + 字母 + 4位数字 + 挂
* 总长7位
*/
static isTrailerPlate(plate: string): boolean {
const reg = new RegExp(`^${this.PROVINCE}[A-HJ-NP-Z][0-9]{4}挂$`);
return reg.test(plate.toUpperCase());
}
/**
* 验证武警车牌 (2013式)
* 格式: WJ + 省份/部门简称 + 5位字符
* 总长8位 (WJ+1+5)
*/
static isArmedPolicePlate(plate: string): boolean {
const reg = /^WJ(?:[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]|[A-HJ-NP-Z])[0-9A-HJ-NP-Z]{5}$/;
return reg.test(plate.toUpperCase());
}
/**
* 验证军队车牌 (2012式)
* 格式: 军种字母 + 字母/数字 + 5位字符
* 总长7位
*/
static isMilitaryPlate(plate: string): boolean {
const reg = /^[VKBHSLJNGCMPEOA][A-HJ-NP-Z0-9][0-9A-HJ-NP-Z]{4}$/;
return reg.test(plate.toUpperCase());
}
/**
* 验证使馆/领馆车牌
* 格式: 使/领 + 6位数字
* 总长7位
*/
static isEmbassyPlate(plate: string): boolean {
const reg = /^[使领][0-9]{6}$/;
return reg.test(plate);
}
/**
* 验证港澳入出境车 (粤Z牌)
* 格式: 粤Z + 4位字符 + 港/澳
* 总长7位
*/
static isHKMacauPlate(plate: string): boolean {
const reg = /^粤Z[A-HJ-NP-Z0-9]{4}[港澳]$/;
return reg.test(plate.toUpperCase());
}
/**
* 验证临时车牌
* 格式: 省份 + 字母 + 5位字符 + 临 / 超
* 总长8位
*/
static isTemporaryPlate(plate: string): boolean {
const reg = new RegExp(`^${this.PROVINCE}[A-HJ-NP-Z][0-9A-HJ-NP-Z]{5}[临超]$`);
return reg.test(plate.toUpperCase());
}
/**
* 验证所有合法车牌(全量)
* @param plate 车牌号码
*/
static isValidPlate(plate: string): boolean {
if (!plate || typeof plate !== 'string') return false;
const upperPlate = plate.toUpperCase().replace(/[·\s-]/g, ''); // 去除分隔符和空格
// 长度预检查:车牌只能是 7 位或 8 位
if (upperPlate.length !== 7 && upperPlate.length !== 8) {
return false;
}
return (
this.isTraditionalPlate(upperPlate) ||
this.isNewEnergyPlate(upperPlate) ||
this.isPolicePlate(upperPlate) ||
this.isCoachPlate(upperPlate) ||
this.isTrailerPlate(upperPlate) ||
this.isArmedPolicePlate(upperPlate) ||
this.isMilitaryPlate(upperPlate) ||
this.isEmbassyPlate(upperPlate) ||
this.isHKMacauPlate(upperPlate) ||
this.isTemporaryPlate(upperPlate)
);
}
}