Source: util/ndn-regex-matcher.js

  1. /**
  2. * Copyright (C) 2014-2016 Regents of the University of California.
  3. * @author: Jeff Thompson <jefft0@remap.ucla.edu>
  4. * From PyNDN ndn_regex.py by Adeola Bannis.
  5. * Originally from Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>.
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. * A copy of the GNU Lesser General Public License is in the file COPYING.
  20. */
  21. /** @ignore */
  22. var Name = require('../name.js').Name;
  23. /**
  24. * An NdnRegexMatcher has static methods to convert an NDN regex
  25. * (http://redmine.named-data.net/projects/ndn-cxx/wiki/Regex) to a JavaScript
  26. * RegExp that can match against URIs.
  27. * @constructor
  28. */
  29. var NdnRegexMatcher = function NdnRegexMatcher()
  30. {
  31. };
  32. exports.NdnRegexMatcher = NdnRegexMatcher;
  33. /**
  34. * Determine if the provided NDN regex matches the given Name.
  35. * @param {string} pattern The NDN regex.
  36. * @param {Name} name The Name to match against the regex.
  37. * @returns {Object} The match object from String.match, or null if the pattern
  38. * does not match.
  39. */
  40. NdnRegexMatcher.match = function(pattern, name)
  41. {
  42. var nameUri = name.toUri();
  43. pattern = NdnRegexMatcher.sanitizeSets(pattern);
  44. pattern = pattern.replace(/<>/g, "(?:<.+?>)");
  45. pattern = pattern.replace(/>/g, "");
  46. pattern = pattern.replace(/<(?!!)/g, "/");
  47. return nameUri.match(new RegExp(pattern));
  48. };
  49. NdnRegexMatcher.sanitizeSets = function(pattern)
  50. {
  51. var newPattern = pattern;
  52. // Positive sets can be changed to (comp1|comp2).
  53. // Negative sets must be changed to negative lookahead assertions.
  54. var regex1 = /\[(\^?)(.*?)\]/g;
  55. var match;
  56. while ((match = regex1.exec(pattern)) !== null) {
  57. // Insert | between components.
  58. // Match 2 is the last match, so we use the hack of working backwards from
  59. // lastIndex. If possible, this should be changed to a more direct solution.
  60. var start = regex1.lastIndex - "]".length - match[2].length;
  61. var end = start + match[2].length;
  62. if (start - end === 0)
  63. continue;
  64. var oldStr = match[2];
  65. var newStr = oldStr.replace(/></g, ">|<");
  66. newPattern = newPattern.substr(0, start) + newStr + newPattern.substr(end);
  67. }
  68. // Replace [] with (), or (?! ) for negative lookahead.
  69. // If we use negative lookahead, we also have to consume one component.
  70. var isNegative = newPattern.indexOf("[^") >= 0;
  71. if (isNegative) {
  72. newPattern = newPattern.replace(/\[\^/g, "(?:(?!");
  73. newPattern = newPattern.replace(/\]/g, ")(?:/.*)*)");
  74. }
  75. else {
  76. newPattern = newPattern.replace(/\[/g, "(");
  77. newPattern = newPattern.replace(/\]/g, ")");
  78. }
  79. return newPattern;
  80. };