jquery.inputmask.regex.extensions.js 11 KB

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