js正则表达式

js正则表达式

做字符串的增删改查

ant-design例子

:formatter="value => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')"
:parser="value => value.replace(/\$\s?|(,*)/g, '')"

简单的sample

常用的方法:

test:返回值是true或false

match:会返回匹配的字符组成的数组。若未匹配到则返回null。

let hd='jingdezhnejig23487669djiel2345';
let nums=[...hd].filter(item => {
  return item>='0' && item<='9'
})
console.log(nums)
nums=[...hd].filter(item => {
  return !Number.isNaN(parseInt(item))
})
console.log(nums)
console.log(hd.match(/\d/g))

创建正则表达式

字面量

不能使用变量,使用变量需要用eval

let hd='jingaghihecjijguirueit';
let a='u';
console.log(eval(`/${a}/g`).test(hd))

new RegExp

let pro = prompt('请输入要高亮的字符,支持正则')
let rg=new RegExp(pro,'g');
let titleDiv=document.querySelector('.title')
titleDiv.innerHTML=titleDiv.innerHTML.replace(rg,(search)=>{
  return `<span style="color:red">${search}</span>`
})

—————————————————————————

选择符

首先,//正则表达式里面的是一个整体。那看的时候怎么去划分。

|:选择符。分道扬镳,左右两种

():分组。子表达式,整个表达式的一部分。

let tel='010-66666666';
// 1.这种问题在于:'010'也会匹配到,因为 | 划分开来了。
console.log(/010|021\-\d{8}/g.test(tel))
// 纠正方法:加上分组()
console.log(/(010|021)\-\d{8}/g.test(tel))
// 2.首尾还要加上^ &
console.log(/^(010|021)\-\d{8}$/g.test(tel))

[] 原子表 和 () 原子组

[]

[xxx]最后整个这里表达的是单个字符。[abcde]表达的是一种或的关系,(a|b|c|d)

只要字符出现在原子表中就匹配,这是可选的意思。

  1. []表达的是一种范围。[a-z],匹配小写字母,这里的 - 表达就是一种范围。[abcde]表达的就是a-e范围。

  2. []中的^符号表达的是取非的意思。比如,[^a-z]非小写字母。

  3. []中的特殊字符会被当做普通字符来看待。例如[(a)],会匹配(、a、)、这三个字符。

几个例子

// 是否全为英文
const str='';
/^[a-zA-Z]+$/.test(str);
// 是否包含英文
/[a-zA-Z]+/.test(str)

正则表达式中中括号的三种用途 [] - JavaShuo

正则表达式(括号)、[中括号]、{大括号}的区别小结 - 安静的女汉纸 - 博客园

() 分组

第三章 正则表达式括号的作用_JavaAlliance-CSDN博客_正则表达式括号

获取(引用)分组

1.match

match返回的结果,在匹配到的情况下,第1个参数是整个匹配的结果,之后就是各个分组匹配到的内容。

2.RegExp.$1-$9

var regex=/(\d{4})-(\d{2})-(\d{2})/;
let dateStr='2021-11-26';
dateStr.match(regex);

console.log(RegExp.$1);

反向引用

引用之前匹配到的分组,就叫反向引用。

\1 匹配之前同样的那个字符,我要和它一样就是这个意思。\2 \3同理

var regex=/\d{4}(-|\/|\.)\d{2}\1\d{2}/;  //下面有代码讲解
var string1="2017-06-12";
var string2="2017/06/12";
var string3="2017.06.12";
var string4="2016-06/12";
console.log(regex.test(string1)); // true
console.log(regex.test(string2)); // true
console.log(regex.test(string3)); // true
console.log(regex.test(string4)); // false

这里有一个很有意思的例子

var regex = /^((\d)(\d(\d)))\1\2\3\4$/;  //下面有代码讲解
var string = "1231231233";
console.log( regex.test(string) ); // true
console.log( RegExp.$1 ); // 123
console.log( RegExp.$2 ); // 1
console.log( RegExp.$3 ); // 23
console.log( RegExp.$4 ); // 3

*有一个例外的情况,当引用的分组不存在时,\会对后面的字符进行转义。\1就表示对后面的1进行了转义。

var regex = /\1\2\3\4\5\6\7\8\9/; console.log( regex.test("\1\2\3\4\5\6\7\8\9") );   //true console.log( "\1\2\3\4\5\6\7\8\9".split("") );//下面有代码讲解

具体案例

首字母转换成大写

// 有几种方法
var regex=/\b[a-zA-Z]/g
var regex=/(?:^|\s)\w/g

var str='my name is lucy !'
const string=str.replace(regex,(c)=>{
    return c.toUpperCase();
})
console.log(string);
// 还有一种做法
name = 'aaa bbb ccc'; 
uw=name.replace(/\b\w+\b/g, function(word){   
    return word.substring(0,1).toUpperCase()+word.substring(1);
});
// https://www.w3school.com.cn/jsref/jsref_replace.asp

转义

\通常表示转义

*题外话

用对象的方式,因为'\d'==='d',所以new RegExp('\\d+\\.\\d+'),可能需要多加一个斜杠。

字符有多个含义,把它转换一下

^ $ :限定边界

^:以xxx开始,限定开始边界

$:以xxx结束,限定结束边界

这是限定我们的边界。表示的是一种完全的严格的验证。

以下是一个例子:

如果不加^$,找到了就认为是成功了;

现在我们需要完全匹配,对整个字符串加以限定。用于进行完整性验证,否则就是部分验证。

<input type="text" name="user">
<span></span>

document.querySelector('input[name="user"]').addEventListener('keyup',function(){
    console.log(this.value)
    var reg=/^[a-zA-Z]{3,6}$/
    var text=reg.test(this.value)?'正确':'错误'
    document.querySelector('span').innerHTML=text
})

元字符

重复量词 表示数量的重复量词匹配的都是一连串的字符串,也就是一种贪婪匹配。

比如\d+

const str='houdunren 2021';
const reg=/\d+/g;
// +:一个或者多个
// 它这里一下就匹配到了4个
str.match(reg); // ['2021']

\d和\D

let str='houdunren 2021';
console.log(str.match(/\D+/g)); // ['houdunren ']

str=`
  张三:010-88888888,李四:021-88888888  
`
// 现在我们想匹配到中文
str.match(/[^:\d-,\s]+/g) // ['张三','李四']

\s和\S

\s表示空白字符:空格、tab、换行符、分页符,这些都是空白字符

\w和\W

这里有一个匹配用户名的例子

需求:以字母开头,后跟字母、数字、下划线,5-10位

综合来使用:结合穷糊匹配,禁止贪婪,模式修正符,断言匹配

const str='8houdunren';
const reg=/^[a-zA-Z]\w{4,9}$/;
console.log(reg.test(str));

点元字符 .

  1. 点元字符:任意字符(除了换行符)。所以你想单纯匹配点就要转义\

let str='https://wetest.qq.com'
let reg=/^https?:\/\/\w+\.\w+\.\w+$/
console.log(str.match(reg))

  1. 但是它无法匹配换行符

s模式:视为单行模式。将换行符当成普通空白来使用。

let hd=`
houdunrencom
houdun
`
console.log(hd);
console.log([...hd]);
console.log(hd.match(/.+/g));
console.log(hd.match(/.+/s));

额外:空格在正则中是普通字符,在正则中直接敲空格就行,或者用\s。

匹配任意一个字符

这种表达方式很巧妙,\s表示的空白,\S表达的是非空白,它们是取非的关系。那我[\s\S]不就表达的是任意字符了么。[\s\S] [\d\D]

let hd=`
<span>
    houdunrencom @@@@@
    houdun
</span>
`
console.log([...hd]);
console.log(hd.match(/<span>[\s\S]+<\/span>/));

表达的范围从小到大:a \d \w . [\s\S]

i与g模式修正符

模式修正符:把正则表达式的运行方式发生改变

/i:忽略大小写。例如邮箱和网址大写也是可以的

/g:全局。贪婪

m模式

这个例子稍微有点复杂

  1. /m:首先多行模式。把每一行单独提取出来匹配,m多行模式主要是针对^$起作用,让它匹配到每一行的头和尾,因为如果不设置/m的话,一个字符串无论是否换行只有一个开始^和结尾$。一个大字符串需要每一行单独处理的时候用m模式就非常合适。

  2. 然后是另外一个细节的点,要注意行首和行尾的空格,有必要时加入\s*

let hd=`
  #1 js,200元 #
  #2 php,300元 #
  #91 houdunren.com # 后盾人
  #3 node.js,180元 #
`
console.log([...hd]);
// console.log(hd.match(/\s*#\d+\s+.+\s+#\s+/g))
// 这里尤其要注意行首行尾的\s*
console.log(hd.match(/^\s*#\d+\s+.+\s+#$/gm))
let lines = hd.match(/^\s*#\d+\s+.+\s+#$/gm);
let lessons=lines.map(line=>{
    console.log(line)
    console.log('line.match===')
    console.log(line.match(/\s*#\d+\s+(.+),(.+)\s+#/))
    let [,name, price]=line.match(/\s*#\d+\s+(.+),(.+)\s+#/);
    // 还有一种方法是使用replace,把头和尾都替换成''
    // let [name,price]=
    // line.replace(/\s*#\d+\s+/,'').replace(/\s+#/,'').split(',')
    return {name,price}
})
console.log('lessons:')
console.log(lessons)

u模式

这里涉及到了很多字符编码的知识点。

【转】正则表达式(三):Unicode诸问题(下)_carvin_happy的专栏-CSDN博客

前端js正则\p的使用, 全局标志g的问题_王为仁的博客-CSDN博客

字符编码笔记:ASCII,Unicode 和 UTF-8 - 阮一峰的网络日志

彻底弄懂 Unicode 编码_hezh1994的博客-CSDN博客_unicode编码

其实这里都是unicode编码的知识。

\p都需要结合/u模式一起来使用

\p{L}:表示字母

\p{N}:表示数字

\p{P}:匹配标点符号

还有它的unicode script属性,可以区分不同国家的语言

let hd=`houdunren2010.不断发布教程,加油!英文标点!`
console.log(hd.match(/\p{P}/gu))
console.log(hd.match(/\p{sc=Han}/gu))

还有一个要注意的:如果遇到宽字节,也就是4个字节的,也需要加上/u

lastIndex与exec方法

exec方法的优势就是能够记录每一个匹配字符串的详细信息,它的原理是改变lastIndex。

获取每一个主信息

var str="I love antzone ,this is animate"; 
var reg=/an/;
console.log('非全局-----------');
console.log(str.match(reg));
console.log('-----------');
console.log(reg.lastIndex);
console.log(reg.exec(str));
console.log(reg.lastIndex);
reg=/an/g;
console.log('全局-----------');
console.log('match-----------');
console.log(reg.lastIndex);
console.log(str.match(reg));
console.log(reg.lastIndex);
console.log('exec-----------');
console.log(reg.lastIndex);
console.log(reg.exec(str));
console.log(reg.lastIndex);
console.log(reg.exec(str));
console.log(reg.lastIndex);
console.log('while-----------');
reg.lastIndex=0;
console.log(reg.lastIndex);
let mat=[]
while(mat=reg.exec(str)){
   console.log(mat); 
}

js正则表达式之exec方法讲解_uwenhao2008的博客-CSDN博客_正则exec

y模式

lastIndex只在g模式和y模式下有效果,其他的情况这个lastIndex其实是被完全忽略掉了。只有g模式和y模式会读取并更新lastIndex的值。

y模式和g模式的区别:g模式会跳过不匹配的字符串,继续向后搜索;而y模式,只要lastIndex当前位置字符串不匹配,就会立马停止不会再继续向后搜索了。那这个就是两者表现上的区别。y 模式表示匹配到不符合的就停掉,不会继续往后匹配,必须连续的符合条件的。

而从语法上来讲,y模式改变了^字符的含义,不再表示整个字符串的开始位置,而是当前的偏移位置。

var re = /^./y; 
console.log(re.test("foo")); //true 
console.log(re.lastIndex); //1 
console.log(re.test("foo")); //true 
console.log(re.lastIndex); //2

JavaScript:正则表达式的/y标识 - 紫云飞 - 博客园

作用:让我们匹配大字符串的时候效率更高

let hd=`后盾人QQ群:6666666666,8888888888,9999999999后盾人不断分享视频教程,后盾人网址是 www.houdunren.com`
let reg=/(\d+),?/y
let res;
console.log('---')
reg.lastIndex=7
let qq=[]
while(res=reg.exec(hd)){
    console.log(res)
    qq.push(res[1])
}
console.log('qq')
console.log(qq)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值