问题-正则使用不熟练 近期一直做表单项校验的工作,所以对正则使用进行一次整理
正则:文本搜索与文本替换 语法:正则表达式主题/修饰符
相关方法
- str.search()
方法用于检索指定子字符串,并返回子字符串的起始位置,找不到返回-1,对大小写敏感(可以修饰符加i,忽略大小写)// 示例 // 正则字符串方法 var str = '这是一个寂寞的Day' // 正则表达式的search方法,用于检索指定字符串的子字符串,并返回子字符串的起始位置 console.log(str.search(/da/)) // 找不到 console.log(str.search(/da/i)) // 忽略大小写,返回找到的字符串的索引值
- str.replace()
用于在字符串中的一些字符替换另一些字符或替换与正则表达式匹配的字符串
语法:str.replace(被替换的字符或规则,替换字符)
默认只替换一次(可以加修饰符g全局替换),对大小写不敏感
// 字符串.replace(被替换的字符或规则,替换的字符)
// 先看一个最简单的replace的例子,这个例子只匹配一回就不往下匹配。
// 匹配不到返回原字符串
var str = "hi,tomtom!"
console.log(str.replace(/kang/, "kangkang"))//hi,tomtom!
console.log(str.replace(/tom/, "kangkang"))//hi,kangkangtom!
// 上面的例子只进行一次替换,遇见第一个匹配的就不往下走了,那么要全局匹配替换应该怎么做呢。
var str = "hi,tomtom!"
console.log(str.replace(/tom/g, "kangkang"))//hi,kangkangkangkang!
// 如果要字母大小写敏感怎么办?看下面的例子
var str = "hi,tomtom!!"
console.log(str.replace(/t/, "T"))//hi,Tomtom!!
// 如果有一些特殊字符需要替换那应该怎么办?例如把下面中的“|”,替换成“,”
var str = "hi,tom|marry!"
console.log(str.replace(/\|/g, ","))//hi,tom|marry!
- str.match()
可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配,
并以数组形式返回匹配结果,匹配不到返回null
单一匹配:不加全局修饰符g时,找到首次匹配的字符串就返回,
返回数组信息包含:
匹配到的字符串,groups是否使用分组,index匹配到的字符串起始下标,input源字符串,length字符串个数
var str = 'Hi,hi,hi,this is big ball?'
console.log(str.match(/is/i))
全局匹配:返回匹配到的长度和各项,对大小写敏感
var str = 'Hi,hi,hi,this is big ball?'
console.log(str.match(/hi/gi))
// 匹配不到返回null
var str = 'Hi,hi,hi,this is big ball?'
console.log(str.match(/cc/g)) // null
- str.split()
用于分割字符串为数组
var str = 'there is Zhongguancun No.1'
str.split() // 返回数组,数组中包括:项 和 长度
// 如下图所示
var str = 'there is Zhongguancun No.1'
str.split('') // 返回数组,以空分割数组(不是空格)
// 以空格分割数组
var str = 'there is Zhongguancun No.1'
str.split(' ') // 返回数组
RegExp对象方法
RegExp对象是一个预定义属性和方法的正则表达式对象
语法格式:var patt = new RegExp(pattern, modifiers);
或者:var patt = /pattern/modifiers
pttern为表达式,modifiers为修饰符用于指定全局匹配g,区分大小写i,和多行比配m。
RegExp对象有三个方法compile()、exec()、test()
- compile()方法,用于在脚本执行过程中编译正则表达式,也可用于改变和重新编译正则表达式。
语法:patt.compile(regexp,modifier)
var str="Every man in the world! Every woman on earth!";
var patt=/man/g;
var str2=str.replace(patt,"person");
// "Every person in the world! Every woperson on earth!"
// 把man 变成了person
patt=/(wo)?man/g;
patt.compile(patt); // 重新编译正则表达式
str2=str.replace(patt,"person");
- exec()方法,用于检索字符串中是否有正则表达式的匹配值,有则返回匹配值,否则返回null。
语法:patt.exec(str);
let str = "aaa";
let r1 = /a/g;
let r2 = /b/g;
console.log("r1匹配结果:", r1.exec(str));
console.log("r2匹配结果:", r2.exec(str));
除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。
let str = "aaa";
let r1 = /a/g;
let r2 = /a/;
console.log("r1匹配结果:", r1.exec(str));
console.log("str-r1匹配结果:", str.match(r1));
console.log("r2匹配结果:", r2.exec(str));
console.log("str-r2匹配结果:", str.match(r2));
我们可以看得出,在调用非全局(上面的例子是全局)的 RegExp 对象的 exec() 方法时,返回的数组与调用方法 String.match() 返回的数组是相同的。
分组情况:
let s = "5aabcaba_a4aba_a a_a_abca_a a a_acbbaa b aa";
let r = /(((a)b)c)|(ba)/g;
console.log(r.exec(s));
此数组的第 0 个元素是与正则表达式相匹配的文本,第 1 个元素是与 RegExpObject 的第 1 个子表达式相匹配的文本(如果有的话),第 2 个元素是与 RegExpObject 的第 2 个子表达式相匹配的文本(如果有的话),以此类推。
- test()方法
test() 方法是正则表达式的一个方法,用于检测一个字符串是否匹配某个模式.
test 方法检查字符串是否与给出的正则表达式模式相匹配,如果是则返回 true,否则就返回 false
语法:regexp.test(str)
一些常见的校验
手机号校验:
非3-3-4格式
export const isMobile = (phone) => {
return /^(13[0-9]|14[5-9]|15[012356789]|166|17[0-8]|18[0-9]|19[8-9])[0-9]{8}$/.test(phone);
}
3-3-4格式
// 手机号 3-4-4格式 非法字符控制输入 vue监听watch中书写
this.threephone = newValue.length > oldValue.length ? newValue.replace(/\D/g,'').replace(/\s/g, '').replace(/(\d{3})(\d{0,4})(\d{0,4})/, '$1 $2 $3') : this.threephone.trim()
// 参数使用
this.userInfo.username = this.threephone.replace(/\s/g, '')
// 数字校验
var phoneReg = function(phone){
return /^(13[0-9]|14[5-9]|15[012356789]|166|17[0-8]|18[0-9]|19[8-9])[0-9]{8}$/.test(phone);
}
密码校验:数字和字母
var passwordReg = function(password){
return (/(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z][\x20-\x7e]{5,20}$/).test(password);
}
// 密码6~12位,同时包含数字,字母,特殊符号(!@#$%^&*-)
var reg = new RegExp('^(?=.*[a-z])(?=.*\\d)(?=.*[#@!~%^&*-])[a-z\\d#@!~%^&*-]{6,12}$', 'i');
if(!reg.test(_this.oldPass)){
_this.oldTip = true;
return false;
}
端口号校验
if(!/^([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/.test(this.port)){
this.$message.warning('请输入合法的端口号')
return
}
ip地址校验
let pattern = /^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$/
if(!pattern.test(this.ip)){
this.$message.warning('请输入合法的IP地址')
return
}
年龄校验
<el-input
placeholder="请输入年龄,如 0~200"
v-model="userInfo.age"
oninput="value=value.replace(/[^\d]/g,'')"
@input="AgeBlur"
@blur="userInfo.age>200 ? $message.warning('请您再确认下年龄'):''"
maxlength="3"
:disabled="globalSign == 'detail' ? true : false"
>
AgeBlur () { // 递归校验年龄
if(this.userInfo.age.search('0') != '0'||(this.userInfo.age.search('0') == '0' && this.userInfo.age.length == 1)){
console.log('当前患者0岁')
return
}
console.log(this.userInfo.age)
console.log(this.userInfo.age.search('0'))
if(this.userInfo.age.search('0') != '-1' && this.userInfo.age.search('0') == '0'){
console.log('首位为0')
this.userInfo.age = this.userInfo.age.replace('0','')
return this.AgeBlur()
}
},
// 身份证号
const isValidIdCards = function (str) { // 封装方法实现非法字符的禁止输入
return (/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/).test(str)
}
// 检测特殊字符
var chackStr = function (str) {
var pattern = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>《》/?~!@#¥……&*()——|{}【】‘;:”“'。,、? ]")
if (pattern.test(str)) {
return true
}
return false
}
// 手机号中间部分****表示 135****946
const isPhone = function (str) {
const newStr = str.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
return newStr
}
邮箱校验
export const isEmail = (s) => {
return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(s)
}
验证URL网址
export const isURL = (s) => {
return /^http[s]?:\/\/.*/.test(s)
}
是否是微信浏览器
export const ua = navigator.userAgent.toLowerCase();
export const isWeiXin = () => {
return ua.match(/microMessenger/i) == 'micromessenger'
}
是否是QQ浏览器
export const isQQBrowser = () => {
return !!ua.match(/mqqbrowser|qzone|qqbrowser|qbwebviewtype/i)
}
是否是移动端
export const isDeviceMobile = () => {
return /android|webos|iphone|ipod|balckberry/i.test(ua)
}
是否为PC端
export const isPC = () => {
let Agents = ["Android", "iPhone",
"SymbianOS", "Windows Phone",
"iPad", "iPod"];
let flag = true;
for (var v = 0; v < Agents.length; v++) {
if (ua.indexOf(Agents[v]) > 0) {
flag = false;
break;
}
}
return flag;
}
是否ios
export const isIos = () => {
if (ua.indexOf('Android') > -1 || ua.indexOf('Linux') > -1) { //安卓手机
return false
} else if (ua.indexOf('iPhone') > -1) {//苹果手机
return true
} else if (ua.indexOf('iPad') > -1) {//iPad
return false
} else if (ua.indexOf('Windows Phone') > -1) {//winphone手机
return false
} else {
return false
}
}
是否是爬虫
export const isSpider = () => {
return /adsbot|googlebot|bingbot|msnbot|yandexbot|baidubot|robot|careerbot|seznambot|bot|baiduspider|jikespider|symantecspider|scannerlwebcrawler|crawler|360spider|sosospider|sogou web sprider|sogou orion spider/.test(ua)
}
获取滚动的坐标
export const getScrollPosition = (el = window) => ({
x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});
滚动到顶部
export const scrollToTop = () => {
const c = document.documentElement.scrollTop || document.body.scrollTop;
if (c > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, c - c / 8);
}
}
洗牌算法随机-数组乱序
export const shuffle = (arr) => {
var result = [],
random;
while (arr.length > 0) {
random = Math.floor(Math.random() * arr.length);
result.push(arr[random])
arr.splice(random, 1)
}
return result;
}
复制内容到剪贴板
export const copyTextToClipboard = (value) => {
var textArea = document.createElement("textarea");
textArea.style.background = 'transparent';
textArea.value = value;
document.body.appendChild(textArea);
textArea.select();
try {
var successful = document.execCommand('copy');
} catch (err) {
console.log('Oops, unable to copy');
}
document.body.removeChild(textArea);
}
严格的身份证校验
export const isCardID = (sId) => {
if (!/(^\d{15}$)|(^\d{17}(\d|X|x)$)/.test(sId)) {
console.log('你输入的身份证长度或格式错误')
return false
}
//身份证城市
var aCity = { 11: "北京", 12: "天津", 13: "河北", 14: "山西", 15: "内蒙古", 21: "辽宁", 22: "吉林", 23: "黑龙江", 31: "上海", 32: "江苏", 33: "浙江", 34: "安徽", 35: "福建", 36: "江西", 37: "山东", 41: "河南", 42: "湖北", 43: "湖南", 44: "广东", 45: "广西", 46: "海南", 50: "重庆", 51: "四川", 52: "贵州", 53: "云南", 54: "西藏", 61: "陕西", 62: "甘肃", 63: "青海", 64: "宁夏", 65: "新疆", 71: "台湾", 81: "香港", 82: "澳门", 91: "国外" };
if (!aCity[parseInt(sId.substr(0, 2))]) {
console.log('你的身份证地区非法')
return false
}
// 出生日期验证
var sBirthday = (sId.substr(6, 4) + "-" + Number(sId.substr(10, 2)) + "-" + Number(sId.substr(12, 2))).replace(/-/g, "/"),
d = new Date(sBirthday)
if (sBirthday != (d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate())) {
console.log('身份证上的出生日期非法')
return false
}
// 身份证号码校验
var sum = 0,
weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2],
codes = "10X98765432"
for (var i = 0; i < sId.length - 1; i++) {
sum += sId[i] * weights[i];
}
var last = codes[sum % 11]; //计算出来的最后一位身份证号码
if (sId[sId.length - 1] != last) {
console.log('你输入的身份证号非法')
return false
}
return true
}
将阿拉伯数字翻译成中文的数字
export const numberToChinese = (num) => {
var AA = new Array("零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十");
var BB = new Array("", "拾", "佰", "仟", "萬", "億", "点", "");
var a = ("" + num).replace(/(^0*)/g, "").split("."),
k = 0,
re = "";
for (var i = a[0].length - 1; i >= 0; i--) {
switch (k) {
case 0:
re = BB[7] + re;
break;
case 4:
if (!new RegExp("0{4}//d{" + (a[0].length - i - 1) + "}$")
.test(a[0]))
re = BB[4] + re;
break;
case 8:
re = BB[5] + re;
BB[7] = BB[5];
k = 0;
break;
}
if (k % 4 == 2 && a[0].charAt(i + 2) != 0 && a[0].charAt(i + 1) == 0)
re = AA[0] + re;
if (a[0].charAt(i) != 0)
re = AA[a[0].charAt(i)] + BB[k % 4] + re;
k++;
}
if (a.length > 1) // 加上小数部分(如果有小数部分)
{
re += BB[6];
for (var i = 0; i < a[1].length; i++)
re += AA[a[1].charAt(i)];
}
if (re == '一十')
re = "十";
if (re.match(/^一/) && re.length == 3)
re = re.replace("一", "");
return re;
}
将数字转换为大写金额
export const changeToChinese = (Num) => {
//判断如果传递进来的不是字符的话转换为字符
if (typeof Num == "number") {
Num = new String(Num);
};
Num = Num.replace(/,/g, "") //替换tomoney()中的“,”
Num = Num.replace(/ /g, "") //替换tomoney()中的空格
Num = Num.replace(/¥/g, "") //替换掉可能出现的¥字符
if (isNaN(Num)) { //验证输入的字符是否为数字
//alert("请检查小写金额是否正确");
return "";
};
//字符处理完毕后开始转换,采用前后两部分分别转换
var part = String(Num).split(".");
var newchar = "";
//小数点前进行转化
for (var i = part[0].length - 1; i >= 0; i--) {
if (part[0].length > 10) {
return "";
//若数量超过拾亿单位,提示
}
var tmpnewchar = ""
var perchar = part[0].charAt(i);
switch (perchar) {
case "0":
tmpnewchar = "零" + tmpnewchar;
break;
case "1":
tmpnewchar = "壹" + tmpnewchar;
break;
case "2":
tmpnewchar = "贰" + tmpnewchar;
break;
case "3":
tmpnewchar = "叁" + tmpnewchar;
break;
case "4":
tmpnewchar = "肆" + tmpnewchar;
break;
case "5":
tmpnewchar = "伍" + tmpnewchar;
break;
case "6":
tmpnewchar = "陆" + tmpnewchar;
break;
case "7":
tmpnewchar = "柒" + tmpnewchar;
break;
case "8":
tmpnewchar = "捌" + tmpnewchar;
break;
case "9":
tmpnewchar = "玖" + tmpnewchar;
break;
}
switch (part[0].length - i - 1) {
case 0:
tmpnewchar = tmpnewchar + "元";
break;
case 1:
if (perchar != 0) tmpnewchar = tmpnewchar + "拾";
break;
case 2:
if (perchar != 0) tmpnewchar = tmpnewchar + "佰";
break;
case 3:
if (perchar != 0) tmpnewchar = tmpnewchar + "仟";
break;
case 4:
tmpnewchar = tmpnewchar + "万";
break;
case 5:
if (perchar != 0) tmpnewchar = tmpnewchar + "拾";
break;
case 6:
if (perchar != 0) tmpnewchar = tmpnewchar + "佰";
break;
case 7:
if (perchar != 0) tmpnewchar = tmpnewchar + "仟";
break;
case 8:
tmpnewchar = tmpnewchar + "亿";
break;
case 9:
tmpnewchar = tmpnewchar + "拾";
break;
}
var newchar = tmpnewchar + newchar;
}
//小数点之后进行转化
if (Num.indexOf(".") != -1) {
if (part[1].length > 2) {
// alert("小数点之后只能保留两位,系统将自动截断");
part[1] = part[1].substr(0, 2)
}
for (i = 0; i < part[1].length; i++) {
tmpnewchar = ""
perchar = part[1].charAt(i)
switch (perchar) {
case "0":
tmpnewchar = "零" + tmpnewchar;
break;
case "1":
tmpnewchar = "壹" + tmpnewchar;
break;
case "2":
tmpnewchar = "贰" + tmpnewchar;
break;
case "3":
tmpnewchar = "叁" + tmpnewchar;
break;
case "4":
tmpnewchar = "肆" + tmpnewchar;
break;
case "5":
tmpnewchar = "伍" + tmpnewchar;
break;
case "6":
tmpnewchar = "陆" + tmpnewchar;
break;
case "7":
tmpnewchar = "柒" + tmpnewchar;
break;
case "8":
tmpnewchar = "捌" + tmpnewchar;
break;
case "9":
tmpnewchar = "玖" + tmpnewchar;
break;
}
if (i == 0) tmpnewchar = tmpnewchar + "角";
if (i == 1) tmpnewchar = tmpnewchar + "分";
newchar = newchar + tmpnewchar;
}
}
//替换所有无用汉字
while (newchar.search("零零") != -1)
newchar = newchar.replace("零零", "零");
newchar = newchar.replace("零亿", "亿");
newchar = newchar.replace("亿万", "亿");
newchar = newchar.replace("零万", "万");
newchar = newchar.replace("零元", "元");
newchar = newchar.replace("零角", "");
newchar = newchar.replace("零分", "");
if (newchar.charAt(newchar.length - 1) == "元") {
newchar = newchar + "整"
}
return newchar;
}
判断一个元素是否在数组中
export const contains = (arr, val) => {
return arr.indexOf(val) != -1 ? true : false;
}
数组去重
export const unique = (arr) => {
return Array.from(new Set(arr));
}
检测密码强度
export const checkPwd = (str) => {
var Lv = 0;
if (str.length < 6) {
return Lv
}
if (/[0-9]/.test(str)) {
Lv++
}
if (/[a-z]/.test(str)) {
Lv++
}
if (/[A-Z]/.test(str)) {
Lv++
}
if (/[\.|-|_]/.test(str)) {
Lv++
}
return Lv;
}