JavaScipt30(第六个案例)(主要知识点:给数字加千分号的正则)

承接上文,这是第6个案例:

附上项目链接: https://github.com/wesbos/JavaScript30

这个主要是要实现在给定的json里匹配出搜索框里的city or state,然后把人口加上千分号,下面是我加了注释的源码:

<script>
    const endpoint =
        'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';

    const cities = [];
    fetch(endpoint)
        .then(blob => blob.json())
        // 扩展运算符(…)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中
        .then(data => cities.push(...data));

    function findMatches(wordToMatch, cities) {
        return cities.filter(place => {
            // here we need to figure out if the city or state matches what was searched
            const regex = new RegExp(wordToMatch, 'gi');
            return place.city.match(regex) || place.state.match(regex)
        });
    }

    function numberWithCommas(x) {
        // 给数字加千分符
        return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
        /*     /\B(?=(\d{3})+(?!\d))/g 这个正则,我正则不太好,所以一开始不知道是什么意思,网上看了下,现在已经完全理解了
            1.元字符\B,其实真正要匹配的是这个,就像语文里面,你是一个和蔼可亲的人,最后要匹配的是人,和蔼可亲是条件,这里其实也是后面一串是条件,我试了下 
            var a = 123456; 
            a.toString().replace(/\b/g, 'aa') //"aa123456aa"  \b匹配的是单词两边的这些空隙
            a.toString().replace(/\B/g, 'aa') //"1aa2aa3aa4aa5aa6" \B和\b是相反的,不属于\b的位置就会被\B匹配到
            2.先行断言?=,我们再来看后面这个,他的作用,举个例子吧,x(?=y),跟着先行断言后面这个的前面那个就会被匹配到,如:xyz,这里x会被匹配,y不会被匹配,
            匹配的是先行断言前面的.在这个正则里面,先行断言后面跟着(\d{3})+,其实是找寻后面跟了3的倍数个数字的位置,像对于一串字符12345来说,
            这个正则表达式匹配1和2,2和3这两位置,因为这两个位置后面都满足跟了3的倍数个数字(234和345),很显然还不满足我们的要求,我们是只要2和3这个位置
            3.后行断言?!,我们想要的情况,是三个三个数字,但是后面不会再跟着数字的情况,?!\d这个就是这个意思
            
            总结: (?=(\d{3})+(?!\d))代表的是:后面需要跟3的倍数个数字,且在这(3的倍数个数字)之后不能再有数字了,他可以是小数点.或字符串尾。
            如12345.67中只有2和3之间的位置满足我们上述的条件。我们只需要指出这个位置,然后将它替换成逗号。
            
            备注:其实后面那个后行断言也可以直接用\b,只要他后面是字符边界,也可以匹配
        */
    }

    function displayMatches() {
        const matchArray = findMatches(this.value, cities);
        const html = matchArray.map(place => {
            const regex = new RegExp(this.value, 'gi');
            // 高亮选中的字符
            const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`);
            const stateName = place.state.replace(regex, `<span class="hl">${this.value}</span>`);
            return `<li>
                    <span class="name">${cityName}, ${stateName}</span>
                    <span class="population">${numberWithCommas(place.population)}</span>
                  </li>`;
        }).join('');
        suggestions.innerHTML = html;
    }

    const searchInput = document.querySelector('.search');
    const suggestions = document.querySelector('.suggestions');

    searchInput.addEventListener('change', displayMatches);
    //这个keyup事件貌似没什么用
    searchInput.addEventListener('keyup', displayMatches);
</script>

 

posted @ 2019-04-03 10:46  来亦何哀  阅读(232)  评论(0编辑  收藏  举报