關於 RegExp s (dotAll) 旗標
1 |
寫了以下程式碼,想用 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 或許可以考慮譯為「標幟」,事實上「幟」一字本身就兼具「旗子」和「記號」的意思。