前端手写题之正则表达式
正则表达式
前端手写题集锦 use js 记录大厂面试常考手写题,github仓库地址:https://github.com/Sunny-117/Front-end-handwritten-question。伴随秋招陆续更新,求star
正则表达式模版字符串
String.prototype.render = function (data) {
return this.replace(/{{[.\s\S]*?}}/g, match => {
if ((match = match.substring(2, match.length - 2).trim()) == "") {
return "";
} else if (match.startsWith("#")) {
return eval(match.substr(1, match.length - 1));
} else {
return data[match] ? data[match] : "";
}
})
}
const data = {
name: "小明",
age: 16,
school: "第三中学",
classroom: "教室2"
}
console.log(
"{{ name }} 今年 {{ age }} 岁,就读于 {{ school }} 今天在 {{ classroom }} 上课,{{ name }} {{ #data.age >= 18 ? '成年了' : '未成年' }}".render(data)
);
// 小明 今年 16 岁,就读于 第三中学 今天在 教室2 上课,小明 未成年
console.log(
`{{name}}说了句{{#
if (data.age >= 18) {
"我已经成年了!"
} else {
"我还没有成年!"
}
}}`.render(data)
);
// 小明说了句我还没有成年! 常写
// 手机号
let reg1 = /^1[44578]\d{9}$/g;
let str1 = '159****9999'
console.log(reg1.test(str1));
// qq号
let reg2 = /^[1-9][0-9]{4,9}$/g;
let str2 = '159222'
console.log(reg2.test(str2));
// 颜色
let reg3 = /#?([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g;
let str3 = '#abc'
console.log(reg3.test(str3));
// 邮箱
let reg4 = /^([A-za-z0-9_\-\.]+)+@([A-za-z0-9_\-\.]+)\.([A-Za-z]{2, 6})$/g;//+一到多
var reg = /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/;
let str4 = 'a11bc@didi.com'
console.log(reg4.test(str4));
字符串的大小写取反
let str = "QIANDUANGOngchengshi猕猴桃Jquery很帅!哈哈 haha";
str = str.replace(/[a-zA-Z]/g, (content) => {
return content.toUpperCase() === content
? content.toLowerCase()
: content.toUpperCase();
});
console.log(str); 检验字符串首尾是否含有数字
let reg = /^\d|\d$/g;//或 let reg2 = /^\d[\s\S]*\d$/g;//都
去除字符串空格
var str = ' as '
//方法1
str = str.replace(/\s*/g,"");//去除所有空格
str = str.replace(/^\s*|\s*$/g,"");//去除两头空格
str = str.replace(/^\s*/,"");//去除左边空
str = str.replace(/(\s*$)/g,"");//去除右边空格
//方法2:trim()方法:只能去除两边空格
function trim(str) {
if (str && typeof str === "string") {
return str.replace(/(^\s*)|(\s*)$/g, "");//去除前后空白符
}
}
//方法3 jquery $.trim(str)
var str = "a2119naskdna";
var newStr = str.replace(/[a-zA-Z]/g, '');//别忘了方括号
console.log(newStr);
const str = ` <div>第一个div</div>
<p>第一个p</p>`
function extract(str) {
return str.replace(/<[^<>]+>/g, "");
}
console.log(extract(str));
驼峰
//横线式
let str = 'hello-world'
function getCamelCase(str) {
let reg = /-(\w)/g;
return str.replace(reg, (_, match) => match.toUpperCase())
}
console.log(getCamelCase(str))// helloWorld
let a='hello world'
let b = a.replace((/\s\w/g),function(v){
return v.substring(1).toUpperCase()
})
console.log(b)
const str = 'helloWorld';
function getKebabCase(str) {
let arr = str.split('');
let result = arr.map((item) => {
if (item.toUpperCase() === item) {
return '-' + item.toLowerCase();
} else {
return item;
}
}).join('');
return result;
}
console.log(getKebabCase(str));
function hump2Underline(s) {
return s.replace(/([A-Z])/g, '_$1').toLowerCase()
} 对象key的驼峰转下划线
const humpToUnderline = function (name) {
let newName = "";
for (const c of name) {
if (c.charCodeAt() <= "Z".charCodeAt() && c.charCodeAt() >= "A".charCodeAt()) {
newName += "_" + c.toLowerCase();
} else {
newName += c;
}
}
return newName;
};
const formatPropertyNamesB = function (obj) {
const names = [];
const unenumerable = {};
for (const key in obj) {
// 属性可配置才进行操作,不可配置的属性忽略
if (Object.getOwnPropertyDescriptor(obj, key).configurable) {
names.push(key);
}
}
// 获取自身的不可枚举但可配置的属性
for (const key of Object.getOwnPropertyNames(obj)) {
if (names.indexOf(key) === -1 && Object.getOwnPropertyDescriptor(obj, key).configurable) {
unenumerable[key] = Object.getOwnPropertyDescriptor(obj, key);
}
}
// 处理可迭代属性
for (const key of names) {
const newKey = humpToUnderline(key);
obj[newKey] = obj[key];
delete obj[key];
}
// 处理不可迭代属性
for (const key in unenumerable) {
const newKey = humpToUnderline(key);
Object.defineProperty(obj, newKey, unenumerable[key]);
delete obj[key];
}
};
// 有带有属性配置的对象
const person2 = {
userName: "Dasen",
userCurrentAge: 23,
};
Object.defineProperty(person2, "nickName", {
configurable: false,
enumerable: true,
value: "Dear Dasen",
});
// nickName 属性不可配置,删除操作会静默失败,结果会多一个重复的属性 nick_name
// formatPropertyNamesA(person2); // {nickName: 'Dear Dasen', user_name: 'Dasen', user_current_age: 23, nick_name: 'Dear Dasen'}
formatPropertyNamesB(person2);
console.log(person2); // {nickName: 'Dear Dasen', user_name: 'Dasen', user_current_age: 23}
console.log(Object.getOwnPropertyDescriptor(person2, "nickName")); // {value: 'Dear Dasen', writable: false, enumerable: true, configurable: false} json对象的key驼峰式转下划线,可以指定层级 递归
function underline2Hump(s) {
return s.replace(/_(\w)/g, function (all, letter) {
return letter.toUpperCase()
})
}
// JSON对象的key值转换为驼峰式
function jsonToHump(obj) {
if (obj instanceof Array) {
obj.forEach(function (v, i) {
jsonToHump(v)
})
} else if (obj instanceof Object) {
Object.keys(obj).forEach(function (key) {
var newKey = underline2Hump(key)
if (newKey !== key) {
obj[newKey] = obj[key]
delete obj[key]
}
jsonToHump(obj[newKey])
})
}
}
const obj = {
demo_demo: 'demo',
a_d: 1,
abcDem: [{
arr_arr: 123
}]
}
jsonToHump(obj)
console.log(obj);
连续的0去掉
var str = "013d1we22ewfa33rr4rwq0dsf00dsf9fas999";
var getNum = function (Str, isFilter) {
//用来判断是否把连续的0去掉
isFilter = isFilter || false;
const finallyResult = [];
// 精髓在正则
var arr = Str.match(isFilter ? /[1-9]\d{1,}/g : /\d{2,}/g);
const result = arr.map(ele => ele);
console.log(result); //连续数字的数组
for (let i = 0; i < result.length; i++) {
if (result[i].length === 3) {
finallyResult.push(result[i]);
}
}
return finallyResult; // 连续的三个数字
};
console.log(getNum(str)); 正则
let str = '((2+3)+(3*4))+2'
function print(str) {
const res = []
matchRes = ''
str = str.replace(/\(\(([\d\D]+)\)\)/g, function (match) {
matchRes = match.substring(1, match.length - 1)
res.push(matchRes)
})
matchRes.replace(/\([\s\S]+?\)/g, function (match) {
// 非贪婪匹配
res.push(match)
})
return res
}
console.log(print(str));// ['(2 + 3)+(3 * 4)', '2 + 3', '3 * 4']
曼迪匹艾公司福利 121人发布