ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript での正規表現の賢い使用例

JavaScript での正規表現の賢い使用例

巴扎黑
巴扎黑オリジナル
2017-08-16 10:50:561445ブラウズ

正規表現を学ぶのに多くの時間を費やして疑問を抱いた子供もいるでしょうが、正規表現はメール アドレスを確認するためだけのものであり、他の場所では基本的に役に立たないことがわかります。人々はそれを難し​​くてほとんど役に立たないと考えて、単にそれを学ばないのです。誰もが知っているように、プログラミングの専門家になりたいなら、正規表現をいじる必要があります。GitHub の優れたオープン ソース ライブラリとフレームワークには、強力な正規表現がたくさんあります。jQuery の作者は、正規表現の星の王子様とも呼ばれていました。それから。ここでは、私が仕事で使用しており、開発者の知恵の火花があらゆる場所で輝いている、正規表現の素晴らしい使用法をいくつか紹介します。
要件を達成するには多くの方法があります。どれが良いでしょうか? 人によって意見は異なります。ここでは、ルールの学習に対する全員の関心を刺激し、ルールを効果的に適用する思考を養うための比較思考のみを提供します。
フロントエンド開発者は常に独自のスキルを持っています。結局のところ、フロントエンド開発はバックエンドとは異なります。コードが冗長である場合、帯域幅が影響を受けます。少なくとも効率は低下します。 Regular Expression (正規表現)、これは割るのが難しいナッツですが、噛むとおいしいです。そこで今日も正規表現の裏技をいくつか紹介します。
正正大法は良いです、正正大法は良いです、正正大法は良いです、重要なことは3回言います。
1. リンクの値を取得します https://www.baidu.com?name=jawil&age=23
非正規実装:

function getParamName(attr) { 
  let search = window.location.search // "?name=jawil&age=23" 
  let param_str = search.split('?')[1] // "name=jawil&age=23" 
  let param_arr = param_str.split('&') // ["name=jawil", "age=23"] 
  let filter_arr = param_arr.filter(ele => { // ["name=jawil"]    return ele.split('=')[0] === attr  }) 
  return decodeURIComponent(filter_arr[0].split('=')[1])}
 console.log(getParamName('name')) // "jawil"


通常の実装を使用します:

function getParamName(attr) { 
  let match = RegExp(`[?&]${attr}=([^&]*)`) //分组运算符是为了把结果存到exec函数返回的结果里    .exec(window.location.search)  //["?name=jawil", "jawil", index: 0, input: "?name=jawil&age=23"]  return match && decodeURIComponent(match[1].replace(/\+/g, ' ')) // url中+号表示空格,要替换掉}
   console.log(getParamName('name'))  // "jawil"


よく理解していない場合は、まず学習してください。この記事を確認してください: [JS 上級] test、exec、match、replace

2. 数値の書式設定の問題、1234567890 --> 1,234,567,890

非正規の実装:

let test = '1234567890'
function formatCash(str) {
    let arr = []
    for (let i = 1; i < str.length; i--) {
        if (str.length % 3 && i == 1) arr.push(str.substr(0, str.length % 3)) if (i % 3 === 0) arr.push(str.substr(i - 2, 3))
    }
    return arr.join(&#39;,&#39;)
}
console.log(formatCash(test)) // 1,234,567,890


通常のルールで実装 :

let test1 = &#39;1234567890&#39;let format = test1.replace(/\B(?=(\d{3})+(?!\d))/g, &#39;,&#39;)
 console.log(format) // 1,234,567,890


通常のルール /B(?=(d{3})+(?!d))/g を簡単に分析してみましょう:

/B(?=(d{3} )+(?!d ))/g: 通常の一致する境界 B、境界の後には (d{3})+(?!d);
(d{3})+: 1 以上である必要があります 3連続する数字;
(?!d): ステップ 2 の 3 つの数字の後に数字を続けることはできません。
(d{3})+(?!d): したがって、一致する境界の後には 3*n が続く必要があります。 (n>=1) の数値。
最後に、一致した境界をすべて置き換えて、目標を達成します。

3. 文字列の左側と右側のスペースを削除します。「jaw il」 --> 「jaw il」 4. 素数であるかどうかの判定 3 --> true

素数は素数とも呼ばれます。 1 より大きく、1 と整数自体を除く他の自然数で割り切れない自然数を指します。
非定期実施:

function trim(str) {
    let start,
    end
    for (let i = 0; i < str.length; i++) {
        if (str[i] !== &#39; &#39;) {
            start = i
            break
        }
    }
    for (let i = str.length - 1; i > 0; i--) {
        if (str[i] !== &#39; &#39;) {
            end = i
            break
        }
    }
    return str.substring(start, end - 1)
}
let str = "  jaw il "console.log(trim(str)) // "jaw il"

通常実施:

function isPrime(num) {return !/^1?$|^(11+?)\1+$/.test(Array(num+1).join(&#39;1&#39;))}
 console.log(isPrime(19)) // true

要使用这个正规则表达式,你需要把自然数转成多个1的字符串,如:2 要写成 “11”, 3 要写成 “111”, 17 要写成“11111111111111111”,这种工作使用一些脚本语言可以轻松的完成,JS实现也很简单,我用Array(num+1).join('1')这种方式实现了一下。
一开始我对这个表达式持怀疑态度,但仔细研究了一下这个表达式,发现是非常合理的,下面,让我带你来细细剖析一下是这个表达式的工作原理。
首先,我们看到这个表达式中有“|”,也就是说这个表达式可以分成两个部分:/^1?$/ 和 /^(11+?)\1+$/
第一部分:/^1?$/, 这个部分相信不用我多说了,其表示匹配“空串”以及字串中只有一个“1”的字符串。
第二部分:/^(11+?)\1+$/ ,这个部分是整个表达式的关键部分。其可以分成两个部分,(11+?) 和 \1+$ ,前半部很简单了,匹配以“11”开头的并重复0或n个1的字符串,后面的部分意思是把前半部分作为一个字串去匹配还剩下的字符串1次或多次(这句话的意思是——剩余的字串的1的个数要是前面字串1个数的整数倍)。
可见这个正规则表达式是取非素数,要得到素数还得要对整个表达式求反。通过上面的分析,我们知道,第二部分是最重要的,对于第二部分,举几个例子,
示例一:判断自然数8。我们可以知道,8转成我们的格式就是“11111111”,对于 (11+?) ,其匹配了“11”,于是还剩下“111111”,而 \1+$ 正好匹配了剩下的“111111”,因为,“11”这个模式在“111111”出现了三次,符合模式匹配,返回true。所以,匹配成功,于是这个数不是质数。
示例二:判断自然数11。转成我们需要的格式是“11111111111”(11个1),对于 (11+?) ,其匹配了“11”(前两个1),还剩下“111111111”(九个1),而 \1+$ 无法为“11”匹配那“九个1”,因为“11”这个模式并没有在“九个1”这个串中正好出现N次。于是,我们的正则表达式引擎会尝试下一种方法,先匹配“111”(前三个1),然后把“111”作为模式去匹配剩下的“11111111”(八个1),很明显,那“八个1”并没有匹配“三个1”多次。所以,引擎会继续向下尝试……直至尝试所有可能都无法匹配成功。所以11是素数。
通过示例二,我们可以得到这样的等价数算算法,正则表达式会匹配这若干个1中有没有出现“二个1”的整数倍,“三个1”的整数倍,“四个1”的整数倍……,而,这正好是我们需要的算素数的算法。现在大家明白了吧。
5、字符串数组去重 ["a","b","c","a","b","c"] --> ["a","b","c"]
这里只考虑最简单字符串的数组去重,暂不考虑,对象,函数,NaN等情况,这种用正则实现起来就吃力不讨好了。
非正则实现:
①ES6实现

let str_arr=["a","b","c","a","b","c"] function unique(arr){  return [...new Set(arr)]}
 console.log(unique(str_arr)) // ["a","b","c"]

②ES5实现

var str_arr = ["a", "b", "c", "a", "b", "c"] function unique(arr) {    return arr.filter(function(ele, index, array) {        return array.indexOf(ele) === index    })}
 console.log(unique(str_arr)) // ["a","b","c"]

③ES3实现

var str_arr = ["a", "b", "c", "a", "b", "c"]
function unique(arr) {
    var obj = {},
    array = []
    for (var i = 0,
    len = arr.length; i < len; i++) {
        var key = arr[i] + typeof arr[i]
        if (!obj[key]) {
            obj[key] = true array.push(arr[i])
        }
    }
    return array
}
console.log(unique(str_arr)) // ["a","b","c"]

额,ES4呢。。。对不起,由于历史原因,ES4改动太大,所以被废弃了。
可以看到从ES3到ES6,代码越来越简洁,JavaScript也越来越强大。

以上がJavaScript での正規表現の賢い使用例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。