javascript - RegExp 在讀取的 HTML 文件上無法工作
首先,我知道大多數正則表達式問題都是怎麼樣的;而這不是那種「請幫我寫程式碼」的問題。
我感到困惑的地方在於,我的 RegExp 在 regexr 上有效,在 Chrome 的開發者工具中輪詢 document.body.textContent 時也有效,但在我用 io.js 讀取 HTML 文件後卻無效。
io.js 是版本 1.5.1,運行於 Windows 8
為什麼它在列出的兩個地方都可以運作,但在 io.js 中卻不行?難道我沒有考慮到 io.js 在讀取文件時會做的某些事情嗎?
我的 RegExp 應該像下面的連結那樣匹配 "@{each ___->___} text and line breaks @{/each}",但它卻返回 null
這是我試圖使用的: http://regexr.com/3aldk
正規表示式:
/@\{each ([a-zA-Z0-9->.]*)\}([\s\S]*)@\{\/each}/gJS(範例):
fs.readFile('view.html', {encoding:'utf8'}, function(error, html) {
console.log(html.match(myRegExp)); // null
});
HTML:
<!doctype html>
<html>
<head>
<title>@{title}</title>
</head>
<body>
<h1>@{foo.bar}</h1>
<p>
Lorem ipsum dolor sit amet, @{foo.baz.hoo}
</p>
@{each people->person}
<div>
<b>@{person.name}:</b> @{person.age}
</div>
@{/each}
</body>
</html>
我是不是漏掉了什麼明顯的東西,比如一個只存在於背面、但從未被使用過的角色?
答案#1
這裡的問題在於 規格 與 實作 之間的微妙界線。
ECMAscript 5.1 規範指出:
一個
-字元可以被當作字面使用,或者它可以表示範圍。如果它是 ClassRanges 的第一個或最後一個字元、範圍規格的起始或終止限制,或者緊跟在範圍規格之後,它就會被當作字面使用。
Regular-Expressions.info 指出:
在字符類中,位於其他位置的連字號如果無法形成範圍,可能會被解釋為字面值或錯誤。不同的正則表達式版本對此非常不一致。
結論:
在字元類別中包含破折號 - 減號的 安全 方法是透過以下任一方式:
- 轉譯它(例如
[a-zA-Z0-9\->.]) 將它放在字元類別的第一個字元(例如
[-.>a-zA-Z0-9])- 例外:在否定字元類別中它排在第二位,就在
^之後(例如[^-.>a-zA-Z0-9])
- 例外:在否定字元類別中它排在第二位,就在
[a-zA-Z0-9.>-])一般程式碼編寫指南建議先放置範圍,並以連字號結尾字元類別,這可以避免歧義並有助於可讀性。
總結來說,你的正則表達式應該變成:
/@\{each ([a-zA-Z0-9>.-]*)\}([\s\S]*)@\{\/each}/g
作為額外的提示:
你也可以把 [\s\S](任何空白字元或任何非空白字元)重寫成 [^](不是沒有)
這將導致你得到以下的正則表達式:
/@\{each ([a-zA-Z0-9>.-]*)\}([^]*)@\{\/each}/g
JavaScript ... 將
[^]視為一個否定的空字符類,匹配任何單一字符。 - 來源
