jquery.inputmask.regex.extensions.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. Input Mask plugin extensions
  3. http://github.com/RobinHerbots/jquery.inputmask
  4. Copyright (c) 2010 - Robin Herbots
  5. Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
  6. Version: 0.0.0-dev
  7. Regex extensions on the jquery.inputmask base
  8. Allows for using regular expressions as a mask
  9. */
  10. (function($) {
  11. $.extend($.inputmask.defaults.aliases, { // $(selector).inputmask("Regex", { regex: "[0-9]*"}
  12. 'Regex': {
  13. mask: "r",
  14. greedy: false,
  15. repeat: "*",
  16. regex: null,
  17. regexTokens: null,
  18. //Thx to https://github.com/slevithan/regex-colorizer for the tokenizer regex
  19. tokenizer: /\[\^?]?(?:[^\\\]]+|\\[\S\s]?)*]?|\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9][0-9]*|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)|\((?:\?[:=!]?)?|(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??|[^.?*+^${[()|\\]+|./g,
  20. quantifierFilter: /[0-9]+[^,]/,
  21. isComplete: function(buffer, opts) {
  22. return new RegExp(opts.regex).test(buffer.join(''));
  23. },
  24. definitions: {
  25. 'r': {
  26. validator: function(chrs, maskset, pos, strict, opts) {
  27. function regexToken(isGroup, isQuantifier) {
  28. this.matches = [];
  29. this.isGroup = isGroup || false;
  30. this.isQuantifier = isQuantifier || false;
  31. this.quantifier = {
  32. min: 1,
  33. max: 1
  34. };
  35. this.repeaterPart = undefined;
  36. }
  37. function analyseRegex() {
  38. var currentToken = new regexToken(),
  39. match, m, opengroups = [];
  40. opts.regexTokens = [];
  41. // The tokenizer regex does most of the tokenization grunt work
  42. while (match = opts.tokenizer.exec(opts.regex)) {
  43. m = match[0];
  44. switch (m.charAt(0)) {
  45. case "(": // Group opening
  46. opengroups.push(new regexToken(true));
  47. break;
  48. case ")": // Group closing
  49. var groupToken = opengroups.pop();
  50. if (opengroups.length > 0) {
  51. opengroups[opengroups.length - 1]["matches"].push(groupToken);
  52. } else {
  53. currentToken.matches.push(groupToken);
  54. }
  55. break;
  56. case "{":
  57. case "+":
  58. case "*": //Quantifier
  59. var quantifierToken = new regexToken(false, true);
  60. m = m.replace(/[{}]/g, "");
  61. var mq = m.split(","),
  62. mq0 = isNaN(mq[0]) ? mq[0] : parseInt(mq[0]),
  63. mq1 = mq.length == 1 ? mq0 : (isNaN(mq[1]) ? mq[1] : parseInt(mq[1]));
  64. quantifierToken.quantifier = {
  65. min: mq0,
  66. max: mq1
  67. };
  68. if (opengroups.length > 0) {
  69. var matches = opengroups[opengroups.length - 1]["matches"];
  70. match = matches.pop();
  71. if (!match["isGroup"]) {
  72. var groupToken = new regexToken(true);
  73. groupToken.matches.push(match);
  74. match = groupToken;
  75. }
  76. matches.push(match);
  77. matches.push(quantifierToken);
  78. } else {
  79. match = currentToken.matches.pop();
  80. if (!match["isGroup"]) {
  81. var groupToken = new regexToken(true);
  82. groupToken.matches.push(match);
  83. match = groupToken;
  84. }
  85. currentToken.matches.push(match);
  86. currentToken.matches.push(quantifierToken);
  87. }
  88. break;
  89. default:
  90. if (opengroups.length > 0) {
  91. opengroups[opengroups.length - 1]["matches"].push(m);
  92. } else {
  93. currentToken.matches.push(m);
  94. }
  95. break;
  96. }
  97. }
  98. if (currentToken.matches.length > 0)
  99. opts.regexTokens.push(currentToken);
  100. };
  101. function validateRegexToken(token, fromGroup) {
  102. var isvalid = false;
  103. if (fromGroup) {
  104. regexPart += "(";
  105. openGroupCount++;
  106. }
  107. for (var mndx = 0; mndx < token["matches"].length; mndx++) {
  108. var matchToken = token["matches"][mndx];
  109. if (matchToken["isGroup"] == true) {
  110. isvalid = validateRegexToken(matchToken, true);
  111. } else if (matchToken["isQuantifier"] == true) {
  112. var crrntndx = $.inArray(matchToken, token["matches"]),
  113. matchGroup = token["matches"][crrntndx - 1];
  114. var regexPartBak = regexPart;
  115. if (isNaN(matchToken.quantifier.max)) {
  116. while (matchToken["repeaterPart"] && matchToken["repeaterPart"] != regexPart && matchToken["repeaterPart"].length > regexPart.length) {
  117. isvalid = validateRegexToken(matchGroup, true);
  118. if (isvalid) break;
  119. }
  120. isvalid = isvalid || validateRegexToken(matchGroup, true);
  121. if (isvalid) matchToken["repeaterPart"] = regexPart;
  122. regexPart = regexPartBak + matchToken.quantifier.max;
  123. } else {
  124. for (var i = 0, qm = matchToken.quantifier.max - 1; i < qm; i++) {
  125. isvalid = validateRegexToken(matchGroup, true);
  126. if (isvalid) break;
  127. }
  128. regexPart = regexPartBak + "{" + matchToken.quantifier.min + "," + matchToken.quantifier.max + "}";
  129. }
  130. } else if (matchToken["matches"] != undefined) {
  131. for (var k = 0; k < matchToken.length; k++) {
  132. isvalid = validateRegexToken(matchToken[k], fromGroup);
  133. if (isvalid) break;
  134. }
  135. } else {
  136. var testExp;
  137. if (matchToken.charAt(0) == "[") {
  138. testExp = regexPart;
  139. testExp += matchToken;
  140. for (var j = 0; j < openGroupCount; j++) {
  141. testExp += ")";
  142. }
  143. var exp = new RegExp("^(" + testExp + ")$");
  144. isvalid = exp.test(bufferStr);
  145. } else {
  146. for (var l = 0, tl = matchToken.length; l < tl; l++) {
  147. if (matchToken.charAt(l) == "\\") continue;
  148. testExp = regexPart;
  149. testExp += matchToken.substr(0, l + 1);
  150. testExp = testExp.replace(/\|$/, "");
  151. for (var j = 0; j < openGroupCount; j++) {
  152. testExp += ")";
  153. }
  154. var exp = new RegExp("^(" + testExp + ")$");
  155. isvalid = exp.test(bufferStr);
  156. if (isvalid) break;
  157. }
  158. }
  159. regexPart += matchToken;
  160. }
  161. if (isvalid) break;
  162. }
  163. if (fromGroup) {
  164. regexPart += ")";
  165. openGroupCount--;
  166. }
  167. return isvalid;
  168. }
  169. if (opts.regexTokens == null) {
  170. analyseRegex();
  171. }
  172. var cbuffer = maskset.buffer.slice(),
  173. regexPart = "",
  174. isValid = false,
  175. openGroupCount = 0;
  176. cbuffer.splice(pos, 0, chrs);
  177. var bufferStr = cbuffer.join('');
  178. for (var i = 0; i < opts.regexTokens.length; i++) {
  179. var regexToken = opts.regexTokens[i];
  180. isValid = validateRegexToken(regexToken, regexToken["isGroup"]);
  181. if (isValid) break;
  182. }
  183. return isValid;
  184. },
  185. cardinality: 1
  186. }
  187. }
  188. }
  189. });
  190. return $.fn.inputmask;
  191. })(jQuery);