iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0
Modern Web

JS 忍者訓練計畫系列 第 15

與正規表達式吵嘴(下) Day14

  • 分享至 

  • xImage
  •  

JavaScript 有許多方法可以搭配正規表式是使用,例如 match, replace, search, split, replaceAll等,或使用 exec 去執行比對。在應用中更多細節像是 ?: (passive subexpression)代表只要 group 就好,並不會被單獨拉出作為捕捉。或更常見的處理字串或空白字元之類等例子。

這章想學到什麼?

  • 捕捉匹配片段
    • 進行簡單地捕捉
    • 使用全域正規表達式進行比對
    • 參照捕捉
    • 不捕捉的群組
  • 使用函式進行置換
  • 運用正規表達式解決常見問題

程式碼閱讀練習與撰寫

捕捉匹配片段

進行簡單地捕捉

function getOpacity(elem) {
    var filter = elem.style.filter;
    return filter ?
    filter.indexOf("opacity") >= 0 ?
        (parseFloat(filter.match(/opacity=([^]+)/)[1]) / 100) + "" : "" : elem.style.opacity;
}

window.onload = function () {
    console.log(getOpacity(document.getElementById("opacity")) == "0.5")
}

使用全域正規表達式進行比對

var all = html.match(/<(\/?)(\w+)([^>]*?)>/g);

參照捕捉

var html = "<div class='test'><b>hello</b><i>world!</i></div>";
var tag = /<(\/?)(\w+)([^>]*?)>/g, match;
var num = 0;

while ((match = tag.exec(html)) !== null) {
    console.log(match.length == 4)
    num++;
}

不捕捉的群組

//?: 為被動子式
var pattern = /((?:ninja-)+)sword/;

var ninjas = "ninja-ninja-sword".match(pattern);

console.log(ninjas.length == 2) //true

使用函式進行置換

"ABCDEfg".replace(/[A-Z]/g, "X");

function upper(all, letter) {
    return letter.toUpperCase();
}

"border-bottom-width".replace(/-(\w)/g, upper) == "borderBottomWidth"

foo=1&foo=2&blah=a&blah=b&foo=3

foo=1, 2, 3&blah=a, b

function compress(source) {
    var keys = {};

    source.replace(
        /([^=&]+)=([^&]*)/g,
        function(full, key, value) {
            keys[key] = (keys[key] ? keys[key] + "," : "") + value;
            retrun "";
        }
    );
    
    var result = [];
    for (var key in keys) {
        result.push(key + "=" + keys[key]);
    }

    return result.join("&");
}

運用正規表達式解決常見問題

修剪字串

function trim(str) {
    return (str || "").replace(/^\s+|\s+$/g, "");
}

trim(" #id div.class ") == "#id div.class"

比對新行

var html = "<b>Hello</b>\n<i>world</i>"
/.*/.exec(html)[0] === "<b>Hello</b>"

/[\S\s]*/.exec(html)[0] === "<b>Hello</b>\n<i>world</i>"

/(?:.|\s)*/.exec(html)[0] === "<b>Hello</b>\n<i>world!</i>"

Unicode

var text = "\u5FCD\u8005\u30D1\u30EF\u30FC";

var matchAll = /[\w\u0080-\uFFFF_-]+/;

console.log((text).match(matchAll))

跳脫字元

var pattern = /^((\w+)|(\\.))+$/;

var test = [
    "formUpdate",
    "form\\.update\\.whatever",
    "form\\:update",
    "\\f\\o\\r\\m\\u\\p\\d\\a\\t\\e",
    "form:update"
]

for (var n = 0; n < tests.length; n++) {
    console.log(pattern.test(tests[n]), tests[n] + 'is a valid identifier');
}

參考資料

https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Guide/Regular_Expressions
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/String/match
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/String/replace
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec


上一篇
與正規表達式吵嘴(上) Day13
下一篇
馴服執行緒和計時器(上) Day15
系列文
JS 忍者訓練計畫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言