寫了以下程式碼,想用 JavaScript RegExp 從一串文字擷取指定 JSON 內容:

<!DOCTYPE html>

<html>

<body>
<textarea id="t" cols="60" rows="8">
var x = 123;
var ctx = {
    Id: "A01",
    Name: "Jeffrey",
    Score: 32767
};
var y = "ABC";
</textarea>
        <div>
            <button id="b">Extract JSON</button>
        </div>
        <script>
            function extractJson(e) {
                var t = document.getElementById("t").innerHTML;
                var m = /ctx = ([{].+[}]);/ims.exec(t);
                if (m) alert(m[1]);
            }
            document.getElementById('b').addEventListener("click", extractJson);
        </script>
</body>

</html>

由於 JSON 內容橫跨多行,依 C# Relguar Expression 經驗,要用 (?ims)ctx = (?<j>[{].+[}]); 搞定,轉成 JavaScript 版應該是 ‵/ctx = ([{].+[}]);/ims.exec(t);,以 Chrome 測試確實管用,順利取出所需的片段:

但同樣程式在 IE11 則會報錯:

調查發現,這是 IE 不支援 /.../ims 的 s 旗標造成。依據 MDN RegExp 說明文件,可用的搜尋旗標有 g 全域、i 不分大小寫、m 多行、y Sticky 查詢(限定與 lastIndex 起始部分吻合)、u Unicode Code Point 比對,的確也沒包含 s - dotAll 模式 (讓萬用字元「.」包含 \r、\n、U+2028、U+2029 等換行符號) 。

dotAll 旗標是在 ES2018 規範才開始納入,IE 不支援也是很正常滴...

所幸,查到一個替代寫法,用 [\s\S] (所有泛空白字元及非空白字元)取代「.」,不用加 s 旗標也能達到相同效果。

dotAll flag is not supported in IE, but fortunately there is a alternative way to accomplish the same result.


Comments

# by Danny Lin

flag 或許可以考慮譯為「標幟」,事實上「幟」一字本身就兼具「旗子」和「記號」的意思。

Post a comment