IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 前端学习日志-2-字符串 -> 正文阅读

[JavaScript知识库]前端学习日志-2-字符串

正则表达式

基本知识

g:全局匹配
i:区分大小写匹配
m:多行匹配

元字符功能
.匹配除换行符以外任何字符
\w匹配字母或数字或下划线或汉字
\s匹配任意空白符
\d匹配数字
\b匹配单词开始或结束
^匹配字符串的开始
$匹配字符串的结束
[]匹配区间
\转义
重复限定符重复次数
*0/更多次
+1/更多次
0/1次
{n}n次
{n,}n/更多次
{n,m}n到m次

实例

括号

分组
/a+/匹配连续出现的“a”,而要匹配连续出现的“ab”时,需要使用/(ab)+/。
其中括号是提供分组功能,使量词“+”作用于“ab”这个整体.
var reg = /(ab)+/g;
var str = "ababa abbb ababab";
console.log( str.match(reg) ); // ["abab", "ab", "ababab"]
分支
在多选分支结构(p1|p2)中,此处括号的作用也是不言而喻的,提供了子表达式的所有可能。
如果去掉正则中的括号,即/^I love JavaScript|Regular Expression$/,
匹配字符串是"I love JavaScript"和"Regular Expression",当然这不是我们想要的。
var reg = /^I love (JavaScript|Regular Expression)$/;
console.log( reg.test("I love JavaScript") ); // true
console.log( reg.test("I love Regular Expression") ); // true
var reg1= /^I love JavaScript|Regular Expression$/;
console.log( reg1.test("I love JavaScript") ); // true
console.log( reg1.test("He hate Regular Expression") ); // true
引用分组
进行数据提取,以及更强大的替换操作

  以日期为例,假设格式是yyyy-mm-dd的,我们可以先写一个简单的正则:
  var reg = /\d{4}-\d{2}-\d{2}/;
  再改成括号版的:
  var reg = /(\d{4})-(\d{2})-(\d{2})/;
  var str = "2017-06-12";
  
  提取年、月、日
  console.log(str.match(reg)); //["2017-06-12", "2017", "06", "12", index: 0, input: "2017-06-12", groups: undefined]
  match返回的一个数组,第一个元素是整体匹配结果,然后是各个分组(括号里)匹配的内容,然后是匹配下标,最后是输入的文本。(注意:如果正则是否有修饰符g,match返回的数组格式是不一样的,例["2017-06-12", "2018-11-23"])。
  
  正则对象exec方法同
  console.log(reg.exec(str)); //["2017-06-12", "2017", "06", "12", index: 0, input: "2017-06-12", groups: undefined]
  
  也可以使用构造函数的全局属性$1至$9来获取
  console.log(RegExp.$1); // "2017"
  console.log(RegExp.$2); // "06"
  console.log(RegExp.$3); // "12"

替换

  yyyy-mm-dd 替换为 mm/dd/yyyy
  replace中的,第二个参数里用$1、$2、$3指代相应的分组。
  var res = str.replace(reg,"$2/$3/$1");
  console.log(res); // "06/12/2017"
  
  等价于
  var res = str.replace(reg, function() {
  return RegExp.$2 + "/" + RegExp.$3 + "/" + RegExp.$1;});
  
  等价于
  var res = str.replace(reg,function(match,year,month,day) {
  return month + "/" + day + "/" + year;});
反向引用

 比如要写一个正则支持匹配如下三种格式:
 2016-06-12
 2016/06/12
 2016.06.12
 
 最可能先想到
 var reg = /\d{4}(-|\/|\.)\d{2}(-|\/|\.)\d{2}/;
 var str = "2017-06-12";
 var str1 = "2017/06/12";
 var str2 = "2017.06.12";
 var str3 = "2016-06/12";
 console.log( reg.test(str) ); // true
 console.log( reg.test(str1) ); // true
 console.log( reg.test(str2) ); // true
 console.log( reg.test(str3) ); // true
 其中/和.需要转义。虽然匹配了要求的情况,但也匹配"2016-06/12"这样的数据
 
 假设我们想要求分割符前后一致怎么办?此时需要使用反向引用
 var reg = /\d{4}(-|\/|\.)\d{2}\1\d{2}/;
 var str = "2017-06-12";
 var str1 = "2017/06/12";
 var str2 = "2017.06.12";
 var str3 = "2016-06/12";
 console.log( reg.test(str) ); // true
 console.log( reg.test(str1) ); // true
 console.log( reg.test(str2) ); // true
 console.log( reg.test(str3) ); // false
 注意里面的\1,表示的引用之前的那个分组(-|\/|\.)。不管它匹配到什么(比如-),\1都匹配那个同样的具体某个字符
 我们知道了\1的含义后,那么\2和\3的概念也就理解了,即分别指代第二个和第三个分组。
 
 看到这里,此时,恐怕你会有三个问题
 1.括号嵌套怎么办?
 以左括号(开括号)为准。比如:
 var reg = /^((\d)(\d(\d)))\1\2\3\4$/;
 var str = "1231231233";
 console.log( reg.test(str) ); // true
 console.log( RegExp.$1 ); // 123
 console.log( RegExp.$2 ); // 1
 console.log( RegExp.$3 ); // 23
 console.log( RegExp.$4 ); // 3
 第一个分组是(\d\d\d),忽略了内嵌的括号,所以\1就是123,’1231231233‘的前三个
 第二个分组是(\d),忽略外嵌套的括号,所以\2就是1,’123‘的第一个
 第三个分组是(\d\d),忽略内外嵌套的括号,所以\3就是23,’123‘的后两个
 第四个分组就是(\d),忽略外嵌套的括号,所以\4就是3,’23‘的后面一个
 确定\1\2\3\4后就可以接着和’1231233‘判断匹配
 即’123 123 1 23 3‘匹配成功
 
 2.\10表示什么呢?
 即\10是表示第10个分组,还是\1和0呢?答案是前者,虽然一个正则里出现\10比较罕见。测试如下:
 var reg = /(1)(2)(3)(4)(5)(6)(7)(8)(9)(#) \10+/;
 var str = "123456789# ######"
 console.log( reg.test(str) ); //true
 
 3.引用不存在的分组会怎样?
 因为反向引用,是引用前面的分组,但我们在正则里引用了不存在的分组时,此时正则不会报错,只是匹配反向引用的字符本身。例如\2,就匹配"\2"。'\2'对2进行了转义
 var reg=/(ab)\1\2/;
 console.log(reg.test('abab\2')); //true
 
 var reg = /\1\2\3\4\5\6\7\8\9/;
 console.log( reg.test("\1\2\3\4\5\6\7\8\9") );  //true
 console.log( "\1\2\3\4\5\6\7\8\9".split("") ); 
 图片不好放,自己f12跑看看
非捕获分组
非捕获性分组工作模式下分组(?:)会作为匹配校验,并出现在匹配结果字符里面,但不作为子匹配返回。
比如利用非捕获性分组获取字符串000aaa111,而且只返回一个值为aaa111的数组:

//先看用捕获性分组匹配会返回什么
var str1 = '000aaa111';             
var pattern = /([a-z]+)(\d+)/; //捕获性分组匹配
var arr = pattern.exec(str1);  
console.log(arr) //['aaa111','aaa','111']   结果子串也获取到了,这并不是我们想要的结果

//非捕获性分组 (?:)
var str2 = '000aaa111';
var pattern2 = /(?:[a-z]+)(?:\d+)/; //非捕获性分组匹配
var arr2 = pattern.exec(str2);  
console.log(arr2) //['aaa111']  结果正确    

前瞻后顾

前瞻 (?=)和(?!) 
前瞻分为正向前瞻和反(负)向前瞻,正向前瞻(?=表达式)表示后面要有什么,反向前瞻(?!表达式)表示后面不能有什么。
前瞻分组会作为匹配校验,但不出现在匹配结果字符里面,而且不作为子匹配返回。如(?=\.jpg),.jpg不出现在返回结果里

正向前瞻匹配一批图片格式,如匹配.jpg后缀文件名
var str = '123.jpg,456.gif,abc.jpg';
var partern = /\w+(?=\.jpg)/g; //正向前瞻匹配
console.log(str.match(partern)); //['123', 'abc']   返回结果正确,没有匹配456.gif

反向前瞻匹配一批字母加数字,如匹配3个及以上的a,而且后面不能有000的字符
var str = 'aaa000 aaaa111 aaaaaaa222';
var partern = /a{3,}(?!000)/g; //反向前瞻匹配
console.log(str.match(partern)); //['aaaa', 'aaaaaaa']   返回结果正确,没有匹配aaa000

前瞻,可以放在位置不固定,可前匹配和后匹配,如:/(?=.jpg)\w+/g;
案例1
模拟trim()函数,去掉字符串头尾的空白符
一、匹配开头结尾的空白符替换成空字符
function trim(str){
  return str.replace(/^\s+|\s+$/g,'');
}
console.log(trim('  foobar  ')); //'foobar' 前后各两空格
二、匹配整个字符串,再提取相应的数据
function trim(str){
  return str.replace(/^\s*(.*?)\s*$/g,'$1');
}
console.log(trim('  foobar  ')); //'foobar' 惰性匹配,前后空格都删掉了
这里使用了惰性匹配*?,不然也会匹配最后一个空格之前的所有空格的
对比
function trim(str){
  return str.replace(/^\s*(.*)\s*$/g,'$1');
}
console.log(trim('  foobar  ')); //‘foobar  ’  贪婪匹配,后面的两个空格保留

惰性匹配,贪婪匹配

惰性符号释义
*?可以重复任意次,但是尽可能重复少的次数
+?可以重复1次或者任意多次,但是尽可能重复少的次数,不过最少次数是1
??可以重复0次或1次,但尽可能少重复
{n,m}?可以重复n到m此,但尽可能少重复,最少匹配次数是n
{n,}?可以重复n次以上,但尽可能少重复,最少匹配n此
贪婪
var s='abbbaabbb123'
var reg=/.*bbb/g;
console.log(reg.exec(s)); //"abbbaabbb"
惰性
var s='abbbaabbb123'
var reg=/.*?bbb/g;
console.log(reg.exec(s)); //"abbb"

函数

test 是regexp的方法,返回的是布尔值,检测对应得字符串是否匹配某种模式 。

var str="catastrop";
var reg= new RegExp("cat","g"); //使用RegExp的模式
var reg1=/cat/g; //字面量模式
var reg2=/dog/g;
console.log(reg.test(str)); //true
console.log(reg1.test(str)); //true
console.log(reg1.test(str)); //false

exce 是regexp的方法,查找并返回当前的匹配结果,以数组(长度为1)的形式返回,不存在返回null

var str="catastrop";
var reg=new RegExp('cat');
var reg1=new RegExp('dog');
var res=reg.exec(str);
var res1=reg1.exec(str);
console.log(res); //["cat", index: 0, input: "catastrop", groups: undefined]
console.log(res1); //null

exec 方法受参数 g 的影响。若指定了 g,则下次调用 exec 时,会从上个匹配的 lastIndex 开始查找。

//非全局
var str = "1a1b1c";
var reg = new RegExp("1.", "");
console.log(reg.exec(str)[0]); //1a
console.log(reg.exec(str)[0]); //1a

//全局
var str = "1a1b1c";
var reg = new RegExp("1.", "g");
console.log(reg.exec(str)[0]); //1a
console.log(reg.exec(str)[0]); //1b

match是 String 对象的一个方法,查找并返回当前的匹配结果,并以数组(长度为1)的形式返回,不存在返回null

var  str="catdogcat";
var reg=new RegExp("cat");
var reg1=new RegExp('lion');
console.log(str.match(reg)); //["cat", index: 0, input: "catdogcat", groups: undefined]
console.log(str.match(reg1)); //null

match的非全局模式跟exec的方法返回值是一样的,如果指定了参数g,那么match一次返回所有结果

var  string="catdogcatdog";
var reg=new RegExp("cat","g");
console.log(string.match(reg)); //["cat", "cat"]

string

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-08 10:37:59  更:2021-09-08 10:39:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:29:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码