JavaScript >> Javascript 文檔 >  >> JavaScript

在 JavaScript 中匹配嵌套結構

過去,我曾談到使用正則表達式將嵌套結構匹配到預定深度,這是您能做的最好的事情,除非您使用三個正則表達式引擎(Perl、PCRE 和 .NET)之一,它們是目前能夠處理真正的遞歸。

好吧,最近我希望能夠在 JavaScript 中匹配字符串時以一種快速、靈活且易於使用的方式支持無限嵌套深度,所以這是我為它編寫的代碼。代碼註釋中包含基本文檔和示例。

// (c) 2007 Steven Levithan <stevenlevithan.com>
// MIT License

/*** matchRecursive
	accepts a string to search and a format (start and end tokens separated by "...").
	returns an array of matches, allowing nested instances of format.

	examples:
		matchRecursive("test",          "(...)")   -> []
		matchRecursive("(t(e)s)()t",    "(...)")   -> ["t(e)s", ""]
		matchRecursive("t<e>>st",       "<...>")   -> ["e"]
		matchRecursive("t<<e>st",       "<...>")   -> ["e"]
		matchRecursive("t<<e>>st",      "<...>")   -> ["<e>"]
		matchRecursive("<|t<e<|s|>t|>", "<|...|>") -> ["t<e<|s|>t"]
*/
var matchRecursive = function () {
	var	formatParts = /^([\S\s]+?)\.\.\.([\S\s]+)/,
		metaChar = /[-[\]{}()*+?.\\^$|,]/g,
		escape = function (str) {
			return str.replace(metaChar, "\\$&");
		};

	return function (str, format) {
		var p = formatParts.exec(format);
		if (!p) throw new Error("format must include start and end tokens separated by '...'");
		if (p[1] == p[2]) throw new Error("start and end format tokens cannot be identical");

		var	opener = p[1],
			closer = p[2],
			/* Use an optimized regex when opener and closer are one character each */
			iterator = new RegExp(format.length == 5 ? "["+escape(opener+closer)+"]" : escape(opener)+"|"+escape(closer), "g"),
			results = [],
			openTokens, matchStartIndex, match;

		do {
			openTokens = 0;
			while (match = iterator.exec(str)) {
				if (match[0] == opener) {
					if (!openTokens)
						matchStartIndex = iterator.lastIndex;
					openTokens++;
				} else if (openTokens) {
					openTokens--;
					if (!openTokens)
						results.push(str.slice(matchStartIndex, match.index));
				}
			}
		} while (openTokens && (iterator.lastIndex = matchStartIndex));

		return results;
	};
}();

你可以在這裡下載代碼。

注意 format 參數需要一個簡單的字符串;不是正則表達式。但是,如果您需要,可以輕鬆修改代碼以使用正則表達式。

更新: 我已經發布了一個替代版本,它接受正則表達式模式作為 matchRecursiveRegExp 格式。


Tutorial JavaScript 教程
  1. 如何讓 SplittingJS 在兩個不同的元素上工作?

  2. 使用 Vue CLI 3/4 添加 Bootstrap 4

  3. 它的技術技能日!

  4. 何時在 Javascript 中使用調用、應用、綁定?

  5. JavaScript 中的異常處理

  6. TypeScripts 枚舉 + JavaScripts in =👍

  7. useState 和 eventHandlers 問題的解決方案

  1. 根據對比度動態改變字體顏色

  2. html5 視頻的 timeupdate 事件多久觸發一次

  3. 用於清單操作的開源 HLS 代理庫

  4. Angular 基礎:在 Angular 中使用枚舉

  5. 前端 JavaScript 新聞簡報(2021 年第二季度)

  6. React Tricks Miniseries 7:如何為不同的數據類型設置狀態

  7. 超越 Angulars 風格指南 - 第 3 部分:符號和文件名

  1. 使用 Simperium 的 Chrome 擴展中的事件和實時消息傳遞

  2. React 沒有在 Windows 中被卸載

  3. React Native 中的 TikTok 動畫

  4. 使用 TypeScript 設置 Express Server 📡