一、 正则的分组
正则的分组:
1: 可以将正则的一部分或者是整体使用小括号括起来,作为一组存在。
组可以作为一个整体去进行匹配,可以加数量词。
2:正则的分组中可以有多个备选方案,使用| 代表或者的意思。
3:正则中的分组,每一组都有一个组号,组号从1开始。组和组之间是可以嵌套的。
组号是根据向右的小括号的顺序号来确定的。
可以根据 RegExp 的静态变量 $+组号的方法来获得对应组匹配到的内容。
一定要先调用test,然后再获得组对应的匹配的内容。
分组最大的意义:根据分组来获得不同组号匹配的子串的内容。
<script>
var str = "hihihihihihihihi";
var reg = /^hihihihihi$/;
var reg = /^(hi){5,8}$/;
console.log (reg.test(str));//true
var reg = /^I love (html|css|js)$/;
console.log (reg.test("I love html"));//true
console.log (reg.test("I love css"));//true
console.log (reg.test("I love js"));//true
console.log (reg.test("I love java"));//false
var str = "2020-08-19";
var reg = /^((\d{4})-(\d{2}))-(\d{2})$/;
console.log (reg.test(str));//true
//根据组号去获得该组号中匹配的子串的内容
console.log (RegExp.$1);//2020-08
console.log (RegExp.$2);//2020
console.log (RegExp.$3);//08
console.log (RegExp.$4);//19
</script>
二、正则对象的实例方法:exec
正则对象的实例方法:exec 是单词execute 缩写。
该方法的主要的作用就是用于字符串中子串的查找。
语法:正则对象.exex(查找的字符串)
注意:
1:该方法每次就返回一个被匹配到的子串内容。
2:如果想获得所有的匹配的子串的内容。加修饰符g。
3:每次调用该方法,都会记录上次匹配结束的位置。下次再次调用从上次匹配结束的位置继续往后匹配。
4:如果匹配完毕之后继续匹配,返回null。然后再次调用该方法,从头匹配。
5: 可以通过分组,对子串中的内容进行获取。
<script>
var str = "12345asdfg_2345asf_345qwe_4567ertyu";
//书写正则匹配上诉的四个子串
var reg = /((\d{3,5})([a-z]{3,5}))/g;
// while(true){
// var result = reg.exec(str);
// if(result === null)break;
// console.log (result);
// }
var result;
while((result = reg.exec(str)) != null){
console.log (RegExp.$1);
console.log (RegExp.$2);
console.log (RegExp.$3);
console.log ("----------")
// console.log (result[0]);
}
</script>
三、 正则的贪婪和懒惰模式
正则的贪婪和懒惰模式:
在正则中的数量词部分。分为了两类。
1:贪婪模式的数量词。尽可能多的去匹配内容。
之前涉及的数量词都是贪婪模式。
2:懒惰模式的数量词,尽可能少的去匹配内容。
通过在贪婪模式的数量词后添加 ? 来启动懒惰模式。
<script>
var str = "12345asdfg";
var reg = /((\d{3,5})([a-z]{3,5}?))/;
reg.test(str);
console.log (RegExp.$1);
</script>
四、正则练习
1:匹配邮政编码:由6个数字构成,第一个不可以是0
2:匹配手机号:由13,15,17,18,开头的11位数字。
3:匹配qq号。第一位不能是0,位数在5-12之间。
4:匹配压缩文件的名称:文件由字母、数字、下划线构成,不可以数字开头
后缀:.zip .rar .gz
5:匹配一个年龄在【18-40】之间
6:匹配身份证号。18位,最后一位可以是X
7:匹配姓名,三个汉字,中间的字必须是 军 或者 君
提示:[\u4e00-\u9fz5] 代表了所有的汉字
<script>
// 1:匹配邮政编码:由6个数字构成,第一个不可以是0
var reg = /^[1-9]\d{5}$/;
// 2:匹配手机号:由13,15,17,18,开头的11位数字。
var reg = /^1[3579]\d{9}$/;
// 3:匹配qq号。第一位不能是0,位数在5-12之间。
var reg = /^[1-9]\d{4,11}$/;
// 4:匹配压缩文件的名称:文件由字母、数字、下划线构成,不可以数字开头
// 后缀:.zip .rar .gz
var reg = /^[a-zA-Z_]\w*\.(zip|rar|gz)$/;
// 5:匹配一个年龄在【18-40】之间
var reg = /^[1][89]$|^[2]\d$|^[3]\d$|^40$/;
console.log (reg.test("17"));//false
console.log (reg.test("18"));//true
console.log (reg.test("20"));//true
console.log (reg.test("32"));//true
console.log (reg.test("40"));//true
console.log (reg.test("41"));//false
// 6:匹配身份证号。18位,最后一位可以是X,不可以0开始。
var reg = /^[1-9]{17}[\dX]$/;
// 7:匹配姓名,三个汉字,中间的字必须是 军 或者 君
// 提示:[\u4e00-\u9fa5] 代表了所有的汉字
var reg = /^[\u4e00-\u9fa5][军君][\u4e00-\u9fa5]$/;
</script>
五、 算法-数组去重-indexOf
数组去重。利用数组的实例方法indexOf 方法。
indexOf:检测当前数组对象中是否包含了指定的元素,包含返回索引,否则-1;
语法:数组.indexOf(key)
思路:遍历原数组,将原数组中的每个元素逐个判断并添加到新的数组中。
如果新数组中已经存在了即将添加的值,就不再添加。只添加没有的元素。
<script>
var arr = [1,2,1,2,1,2,1,2,1,2,1,1,1,1,1,2,2,2,2];
//对指定的数组去重。
function unique(arr) {
if(!Array.isArray(arr))
return;
const LEN = arr.length;
if(LEN === 0)
return;
var newArr = [];
for (let i = 0; i < LEN; i++) {
var ele = arr[i];
//no problem
// if(newArr.indexOf(ele) === -1){
// newArr.push(ele);
// }
if(newArr.indexOf(ele) >= 0)
continue;
newArr.push(ele);
}
return newArr;
}
console.log (unique(arr));
</script>
六、算法-数组去重-splice
数组去重:使用数组的实例方法splice方法。直接删除原数组中的内容。
splice:可以对数组实现增删改的操作。
思路:遍历数组,用当前数组元素和后续的元素逐个比较,后续的元素只要和当前的元素相同就被删掉。
<script>
var arr = [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2];
//对指定的数组去重。
(function (arr) {
if (!Array.isArray (arr))
return;
const LEN = arr.length;
if (LEN === 0)
return;
//外层用户获得每一个元素。
for (let i = 0; i < arr.length; i++) {
//内层循环用于当前i对应的元素和i后续的所有的元素比较
var value = arr[i];
for (let j = i + 1; j < arr.length; j++) {
if (value === arr[j]) {
//删除j位置上的元素。//j--的意思:删除了j位置上的元素,后续的元素就补上来了。
//j位置上的元素需要重新判断。j--是为了抵消j++。保证此次的j的值不发生变化,、
//继续判断j位置的元素。
arr.splice (j--, 1);
}
}
}
})(arr);
console.log (arr);
</script>
七、算法-数组去重-哈希
哈希去重:根据哈希数据结构的特点。哈希中的数据都是键值对数据。
key+value的形式。key是具有唯一性的。
实现的思路:将数组的所有的元素都作为对象的key添加到对象中。value是无所谓的。
对象中的所有的key就是去重之后的结果。
<script>
var arr = [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2];
//对指定的数组去重。
function unique(arr) {
if (!Array.isArray (arr))
return;
const LEN = arr.length;
if (LEN === 0)
return;
var newArr = [];
var obj = {};
//遍历数组的元素。
for (let i = 0; i < arr.length; i++) {
//如果arr[i]还不是obj的key。存在的话就不再添加。实现去重。
if(!obj[arr[i]]){
obj[arr[i]] = "a";
newArr.push(arr[i]);
}
}
return newArr;
//得到对象的所有的key.结果是字符串类型。
// return Object.keys(obj);
};
console.log (unique(arr));
</script>
八、算法-数组去重-冒泡
冒泡排序的实现:
<script>
function random(min, max) {
return ~~(Math.random () * (max - min) + min);
}
function randomArray(len, min, max) {
var arr = [];
for (let i = 0; i < len; i++) {
arr[i] = random (min, max);
}
return arr;
}
function bubbleSort(arr) {
if (!Array.isArray (arr))
return;
const LEN = arr.length;
if (LEN === 0)
return;
//外层循环控制趟数
for (let i = 0; i < LEN - 1; i++) {
//内层控制第i趟的相邻元素之间的比较和交换。
var flag = false;
for (let j = 0; j < LEN - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
flag = true;
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
if (!flag) {
return;
}
}
}
(function () {
var array = randomArray (10, 0, 100);
console.log (array);
setTimeout (function () {
bubbleSort (array);
console.log (array);
}, 1000);
}) ();
</script>
九、算法-排序-选择排序
<script>
// 内层循环控制本趟的无序区的最小元素的查找。
// 外层循环外,无序区的最小元素和无序区的第一个元素互换。
function random(min, max) {
return ~~(Math.random () * (max - min) + min);
}
function randomArray(len, min, max) {
var arr = [];
for (let i = 0; i < len; i++) {
arr[i] = random (min, max);
}
return arr;
}
//对指定的数组进行选择排序
function selectSort(arr) {
if (!Array.isArray (arr))
return;
const LEN = arr.length;
if (LEN === 0)
return;
//外层循环控制趟数。长度-1
//i即作为外层循环的控制变量,也作为无序区的第一个元素的索引。
for (let i = 0; i < LEN - 1; i++) {
//无序区的最小元素的索引。
//先假设无序区的最小元素的索引是无序区的第一个元素。
var minIndex = i;
//内层循环控制第i趟的最小元素的查找。
for (let j = i + 1; j < LEN; j++) {
//找最小元素索引的过程。
if (arr[j] < arr[minIndex]) {
//minIndex永远保存的是最小元素的索引。
minIndex = j;
}
}
//内层循环外。最小元素和无序区第一个元素互换。
if(minIndex !== i){
//无序区的第一个元素不是最小元素。
var temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
}
(function () {
var array = randomArray (10, 0, 100);
console.log (array);
setTimeout (function () {
selectSort (array);
console.log (array);
}, 1000);
}) ();
</script>
十、算法-排序-插入排序
<script>
/*
插入排序的核心思想:将无序区的第一个元素,插入到有序区的合适的位置。
*
* */
function random(min, max) {
return ~~(Math.random () * (max - min) + min);
}
function randomArray(len, min, max) {
var arr = [];
for (let i = 0; i < len; i++) {
arr[i] = random (min, max);
}
return arr;
}
function insertSort(arr) {
if (!Array.isArray (arr))
return;
const LEN = arr.length;
if (LEN === 0)
return;
//外层循环控制趟数。i还用来代表无序区的第一个元素的索引。
for (let i = 1; i < LEN; i++) {
//备份无序区的第一个元素。
var temp = arr[i];
//内层循环负责第i趟的有序区的元素的比较和移动。
//j逆序取到有序区的所有的元素。
for (var j = i - 1; j >= 0 && arr[j] > temp; j--) {
//后移动元素
arr[j+1] = arr[j];
}
//将备份的数据,插入到合适的位置。
arr[j+1] = temp;
}
}
function insertSort1(arr) {
if (!Array.isArray (arr))
return;
const LEN = arr.length;
if (LEN === 0)
return;
//外层循环控制趟数。i还用来代表无序区的第一个元素的索引。
for (let i = 1; i < LEN; i++) {
//备份无序区的第一个元素。
var temp = arr[i];
//内层循环负责第i趟的有序区的元素的比较和移动。
//j逆序取到有序区的所有的元素。
for (var j = i - 1; j >= 0; j--) {
//有序区的遍历的元素比待插入的元素大。
if(arr[j] > temp){
//后移动元素
arr[j+1] = arr[j];
}else{
break;
}
}
//将备份的数据,插入到合适的位置。
arr[j+1] = temp;
}
}
(function () {
var array = randomArray (10, 0, 100);
console.log (array);
setTimeout (function () {
insertSort1 (array);
console.log (array);
}, 1000);
}) ();
</script>