JS String 中常用查找API的高级用法

544 阅读3分钟

可能你知道正则表达式,可能你也知道js中的查找相关的函数( indexOf search replace... )。那查找函数+正则表达式你知不知道?如果不知道哪你就来对地方了

我们常见的字符串查找相关的API有一下几个

函数名称作用
indexOf()查找一个固定的关键词出现的位置
search()用正则查找一个关键词
match()只查找第一个关键词的内容
reg.exec()正则对象查找关键词的内容及位置
replace替换字符串
split切割字符串

我们平常可能也就简单的使用一下indexOf、replace、split函数,但是有些场景如果配合着正则表达式的方式使用可能会更方便高效。今天我们就来逐个介绍一下。

1. string.indexOf()

string.indexOf()的基础用法如下

/*
    从下标from_index(可选)处开始查找关键词,并返回关键词对位置,未找到返回-1
*/
let index = str.indexOf("关键词"[,from_index])

但是我们要知道,这个API就只能找到一种固定的关键词,而且不支持正则。其用法如下:

// 我的朋友在哪?
let str = "朋友,你好"
let target = str.indexOf("朋友")
console.log("你的朋友出现在" + target + "处")

// 小明在哪?
let target_xiaoming = str.indexOf("小明");
if (target_xiaoming > 0) {
    console.log("小明在"+target_xiaoming+"处")
} else {
    console.log("未找到小明")
}

那如果我要用到正则表达式来查找怎么办? 咱也不用着急,接着往下看。

2. string.search()

这个API的返回值和indexOf一样,但是他支持正则表达式,这样就弥补了indexOf的缺陷,用法如下:

/*
    用正则查找一个关键词的位置,返回值是关键词的下标
*/
let i=str.search(/正则/)

但是他查找时有两个问题一是正则表达式默认区分大小写,要解决这一点我们可以通过在正则表达式第二个 / 后加i(ignore)来忽略大小写的限制。二是无法获取关键词的内容,要解决这点,只能通过其他方式。相关示例如下:

    let str = '小明说:我Cao,你真好看!';
    let target = str.search(/([我卧]|cao)\s*([操草曹艹]|cao)/i);

    if (target > 0) {
        console.log(`在位置${target}处发现敏感词`);
    } else {
        console.log("无敏感词")
    }

我们用str.search()可以知道关键词的位置,但是查找到的关键词是什么,我们不知道。所以就可以用下面的方法来查找。

3. string.match()

match的用法比较多,返回的信息也比较全面,是一个数组,里面包含了关键词和关键词的下标,我们分两块来认识它。

  1. 只查找第一个关键词的内容

    let arr=str.match(/正则/i)
    //返回值: arr:[ 0: "关键词",  index: 下标i ]
    //如果没找到,返回null
    

    这种用法只能找到一个关键词,示例如下

    let str = '小明说:我Cao,你真好看!';
    let arr=str.match(/([我卧]|cao)\s*([操草曹艹]|cao)/i);
    
    console.log(arr)// ['我Cao', '我', 'Cao', index: 4, input: '小明说:我Cao,你真好看!', groups: undefined]
    if(arr!=null){
        console.log(`在位置${arr["index"]}处发现敏感词${arr[0]}`);
    }else{
        console.log('无敏感词');
    }
    

    这个函数我们要熟悉的就是他的返回值的格式,他是一个类数组对象,前面可以通过下标的方式遍历他找出来的关键词,而像 index,和input这些索引就存放着下标信息和原文。可以直接通过索引拿出来。

  2. 查找所有关键词的内容

    其实,这个用法和上面的区别只是在正则表达式的第二个/后面加一个g,我门要了解的就是它的返回数据的格式。

     let str = "老师:请用小红、我的、朋友三个词造句。小亮:小红是我的朋友!小然:朋友小红是我的!";
     let arr = str.match(/小[\u4e00-\u9fa5/]/ig);
     console.log(arr) //['小红', '小亮', '小红', '小然', '小红']
    

    加了g之后他的返回值就和之前不一样了,里面只有关键词的信息,这是我们要注意的。 什么?位置有没有了?好吧,以为找到一个万能药,结果又不行。悲催,不过也不是没有办法,不然regx.exec()就没有用了。

4. reg.exec

通过正则对象查找数据,用法如下:

let reg = /小[\u4e00-\u9fa5/]/ig
let str = "老师:请用小红、我的、朋友三个词造句。小亮:小红是我的朋友!小然:朋友小红是我的!";
console.log(reg.exec(str)) 
// ['小红', index: 5, input: '老师:请用小红、我的、朋友三个词造句。小亮:小红是我的朋友!小然:朋友小红是我的!', groups: undefined]

console.log(reg.exec(str)) 
// ['小亮', index: 19, input: '老师:请用小红、我的、朋友三个词造句。小亮:小红是我的朋友!小然:朋友小红是我的!', groups: undefined]

console.log(reg.exec(str)) 
// ['小红', index: 22, input: '老师:请用小红、我的、朋友三个词造句。小亮:小红是我的朋友!小然:朋友小红是我的!', groups: undefined]

console.log(reg.exec(str)) 
//['小然', index: 30, input: '老师:请用小红、我的、朋友三个词造句。小亮:小红是我的朋友!小然:朋友小红是我的!', groups: undefined]

console.log(reg.exec(str))
//['小红', index: 35, input: '老师:请用小红、我的、朋友三个词造句。小亮:小红是我的朋友!小然:朋友小红是我的!', groups: undefined]0: "小红"groups: undefinedindex: 35input: "老师:请用小红、我的、朋友三个词造句。小亮:小红是我的朋友!小然:朋友小红是我的!"length: 1[[Prototype]]: Array(0)

console.log(reg.exec(str)) 
// null

可以看出,这个方法没执行一次就会返回下一个符合正则表达式的关键词的位置,直到为空。之后就再次从头开始找。

5. string.replace()

这个API配合着正则表达式还是蛮好用的,他的用法有两种。

  1. 简单替换:将所有的关键词替换为相同的值
    str = str.replace(/正则/g,"新词")
    
    示例如下:
    let msg = "老师:请用小红、我的、朋友三个词造句。小亮:小红是我的朋友!小然:朋友小红是我的!";
    let arr = msg.match(/小[\u4e00-\u9fa5/]/ig);
    msg = msg.replace(/小[\u4e00-\u9fa5/]/ig,"小*");
    
    console.log(msg); 
    //老师:请用小*、我的、朋友三个词造句。小*:小*是我的朋友!小*:朋友小*是我的!
    console.log(`共替换${arr!=null?arr.length:0}处`);
    // 共替换5处
    
  2. 高级替换:根据每个关键词的不同,动态生成新值替换
    str = str.replace(/正则/g,(kw) => {
        return xxx;
    })
    
    这个用法比较特殊,每当正则表达式发现一个关键词时,他就会将这个关键词作为入参放入回调函数中。回调函数返回的值会替换原来被搜索到的关键词 示例如下:
    let str="good good study, day day up!";
    let reg=/\b[a-z]/g;
    let arr=str.match(reg);
    str=str.replace(reg,function(kw){
        return kw.toUpperCase();
    });
    console.log(str); //Good Good Study, Day Day Up!
    console.log("共替换"+arr.length+"处");//共替换6处
    

6. string.split()

split()这个函数也是比较常用的,他的功能是按照制定的切割符,将字符串切割为多段字符串。

let arr=str.split("切割符");

示例如下:

    //将查询字符串变为对象
    let src = "?uname=dingding&upwd=123456&fav=游泳&fav=跑步";

    //将第一个问号切割掉
    src = src.slice(1);
            
    //以&为分隔符,将字符串分隔出来
    let arr = src.split("&");

    console.log(arr);
    /*
        arr:[
            'uname=dingding', 
            'upwd=123456', 
            'fav=游泳', 
            'fav=跑步'
        ] 
    */
    
    let obj={};
    // 把arr中的每项拿出来单独切割
    for(let i=0;i<arr.length;i++){
        let arr2 = arr[i].split("=");
        obj[arr2[0]]=arr2[1];
    }
    console.log(obj);
    /*
    obj:{
        uname: 'dingding', 
        upwd: '123456', 
        fav: '跑步'
    }
    */

但如果切割符号会发生变化,那么就要用到正则表达式了

let arr=str.split(/正则/i);

我们来看看具体的例子:

<body>
    <ul id="ulScores">
        <li>98</li>
        <li>97</li>
        <li>100</li>
        <li>91</li>
    </ul>
    <script>
        // 将页面中的分数由高到低排序
        var html = ulScores.innerHTML;
        html=html.replace(/^\s*<li>/,"");
        html=html.replace(/<\/li>\s*$/,"");
        scores=html.split(/<\/li>\s*<li>/ig);
        scores.sort((a,b)=>b-a);   
        html = "<li>" + scores.join("</li><li>") + "<\li>";
        ulScores.innerHTML = html;
    </script>
</body>

以上就是我要给大家分享的内容了,如果大家觉得写的不错就收藏一下吧。

温馨提示:看懂不如会用哦,跟着示例敲几遍吧,和这几个API交个朋友。 如果有写的不对的地方欢迎指正,我们也交个朋友!