![]() ![]() |
websvn |
Subversion Repositories: |
Compare with Previous - Blame - Download
/*ParseMaster, version 1.0 (pre-release) (2005/05/12) x6Copyright 2005, Dean EdwardsWeb: http://dean.edwards.name/This software is licensed under the CC-GNU LGPLWeb: http://creativecommons.org/licenses/LGPL/2.1/*//* a multi-pattern parser *//* --- (include) http://dean.edwards.name/my/fix-ie5.js --- *//* --- (require) http://dean.edwards.name/common/common.js --- */function ParseMaster() {// constantsvar $EXPRESSION = 0, $REPLACEMENT = 1, $LENGTH = 2;// used to determine nesting levelsvar $GROUPS = /\(/g, $SUB_REPLACE = /\$\d/, $INDEXED = /^\$\d+$/,$TRIM = /(['"])\1\+(.*)\+\1\1$/, $$ESCAPE = /\\./g, $QUOTE = /'/,$$DELETED = /\001[^\001]*\001/g;function $DELETE($match, $offset){return "\001" + $match[$offset] + "\001"};// publicthis.add = function($expression, $replacement) {if (!$replacement) $replacement = $DELETE;// count the number of sub-expressions// - add one because each pattern is itself a sub-expressionvar $length = (_internalEscape(String($expression)).match($GROUPS) || "").length + 1;// does the pattern deal with sub-expressions?if (typeof $replacement == "string" && $SUB_REPLACE.test($replacement)) {// a simple lookup? (e.g. "$2")if ($INDEXED.test($replacement)) {// store the index (used for fast retrieval of matched strings)$replacement = parseInt($replacement.slice(1)) - 1;} else { // a complicated lookup (e.g. "Hello $2 $1")// build a function to do the lookupvar i = $length;var $quote = $QUOTE.test(_internalEscape($replacement)) ? '"' : "'";while (i) $replacement = $replacement.split("$" + i--).join($quote + "+a[o+" + i + "]+" + $quote);$replacement = new Function("a,o", "return" + $quote + $replacement.replace($TRIM, "$1") + $quote);}}// pass the modified arguments_add($expression || "/^$/", $replacement, $length);};// execute the global replacementthis.exec = function($string) {return _unescape(_escape($string, this.escapeChar).replace(new RegExp(_patterns, this.ignoreCase ? "gi" : "g"), _replacement), this.escapeChar).replace($$DELETED, "");};// clear the patterns collections so that this object may be re-usedthis.reset = function() {_patterns.length = 0;};// privatevar _patterns = []; // patterns stored by indexvar _toString = function(){return "(" + String(this[$EXPRESSION]).slice(1, -1) + ")"};_patterns.toString = function(){return this.join("|")};// create and add a new pattern to the patterns collectionfunction _add() {arguments.toString = _toString;// store the pattern - as an arguments object (i think this is quicker..?)_patterns[_patterns.length] = arguments;}// this is the global replace function (it's quite complicated)function _replacement() {if (!arguments[0]) return "";var i = 1, j = 0, $pattern;// loop through the patternswhile ($pattern = _patterns[j++]) {// do we have a result?if (arguments[i]) {var $replacement = $pattern[$REPLACEMENT];switch (typeof $replacement) {case "function": return $replacement(arguments, i);case "number": return arguments[$replacement + i];default: return $replacement;}// skip over references to sub-expressions} else i += $pattern[$LENGTH];}};// encode escaped charactersvar _escaped = [];function _escape($string, $escapeChar) {return $escapeChar ? $string.replace(new RegExp("\\" + $escapeChar + "(.)", "g"), function($match, $char) {_escaped[_escaped.length] = $char;return $escapeChar;}) : $string;};// decode escaped charactersfunction _unescape($string, $escapeChar) {var i = 0;return $escapeChar ? $string.replace(new RegExp("\\" + $escapeChar, "g"), function() {return $escapeChar + (_escaped[i++] || "");}) : $string;};function _internalEscape($string) {return $string.replace($$ESCAPE, "");};};Common.specialize({constructor: ParseMaster,ignoreCase: false,escapeChar: ""});