Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Basic replace support

  • Loading branch information...
commit eaf4c857a57be6416c97575922060daf11f5877d 1 parent 55eed54
Daniel Lo Nigro authored

Showing 2 changed files with 59 additions and 8 deletions. Show diff stats Hide diff stats

  1. +36 7 NamedRegExp.js
  2. +23 1 NamedRegExp.spec.js
43 NamedRegExp.js
@@ -8,14 +8,20 @@
8 8
9 9 var
10 10 // Native RegExp object prototype
11   - nativeProto = RegExp.prototype,
  11 + nativeRegex = RegExp.prototype,
  12 + nativeExec = nativeRegex.exec,
  13 +
  14 + nativeString = String.prototype,
  15 + nativeReplace = nativeString.replace,
12 16 // Named group - Matches (?P<name>....)
13   - group = /\(\?P<([^>]+)>/g;
  17 + group = /\(\?P<([^>]+)>/g,
  18 + // Backreference - Matches \k<name>
  19 + backref = /\\k<([^>]+)>/g;
14 20
15 21 // Exec function that takes named groups into account
16 22 var exec = function (string) {
17 23 // Perform native regex match
18   - var result = nativeProto.exec.call(this, string);
  24 + var result = nativeExec.call(this, string);
19 25
20 26 // Ensure result isn't null
21 27 if (!result)
@@ -30,12 +36,14 @@
30 36 };
31 37
32 38 // Constructor for NamedRegExp
33   - return function (pattern, flags) {
34   - var groups = [];
  39 + var NamedRegExp = function NamedRegExp (pattern, flags) {
  40 + var groups = [],
  41 + groupIndices = {};
35 42
36 43 // Go through all named groups
37 44 var newPattern = pattern.replace(group, function (match, name, offset, string) {
38   - groups.push(name);
  45 + // Array#push returns the array length, which is the same as the regex replacement index.
  46 + groupIndices[name] = groups.push(name);
39 47 return '(';
40 48 });
41 49
@@ -46,6 +54,7 @@
46 54 // Properties
47 55 regexp.isNamed = true;
48 56 regexp.namedGroups = groups;
  57 + regexp.namedGroupIndices = groupIndices;
49 58 regexp.originalSource = pattern;
50 59
51 60 // Methods
@@ -53,4 +62,24 @@
53 62
54 63 return regexp;
55 64 }
56   -})();
  65 +
  66 + /**
  67 + * Returns a new string with some or all matches of a `pattern`` replaced by a `replacement`.
  68 + * @param {String} string Input string to search for replacements in
  69 + * @param {RegExp|String} pattern Pattern to replace
  70 + * @param {String|Function} replacement What to replace `pattern` with
  71 + * @return {String} A new string with all the patterns replaced
  72 + */
  73 + NamedRegExp.replace = function replace(string, pattern, replacement) {
  74 + if (typeof(replacement) !== 'function') {
  75 + // Switch the named backreferences with their index
  76 + var replacement = replacement.replace(backref, function (match, name) {
  77 + return '$' + pattern.namedGroupIndices[name];
  78 + });
  79 + }
  80 +
  81 + return string.replace(pattern, replacement);
  82 + }
  83 +
  84 + return NamedRegExp;
  85 +})();
24 NamedRegExp.spec.js
@@ -23,4 +23,26 @@ describe('NamedRegExp', function () {
23 23 expect(result.name).toBe('Daniel');
24 24 expect(result.year).toBe('2012');
25 25 });
26   -});
  26 +
  27 + describe('replace', function () {
  28 + it('should function as a static method', function () {
  29 + var regexp = new NamedRegExp('^(?P<helloworld>\\d+)$');
  30 + var input = '12345';
  31 + var replacement = 'aaa \\k<helloworld> bbb';
  32 + var expected = 'aaa 12345 bbb';
  33 +
  34 + var result = NamedRegExp.replace(input, regexp, replacement);
  35 + expect(result).toBe(expected);
  36 + });
  37 +
  38 + it('should support replacing two groups', function () {
  39 + var regexp = new NamedRegExp('^(?P<year>\\d+) is (?P<msg>.+)$');
  40 + var input = '2012 is awesome';
  41 + var replacement = 'It\'s \\k<msg> in \\k<year>!';
  42 + var expected = 'It\'s awesome in 2012!';
  43 +
  44 + var result = NamedRegExp.replace(input, regexp, replacement);
  45 + expect(result).toBe(expected);
  46 + });
  47 + })
  48 +});

0 comments on commit eaf4c85

Please sign in to comment.
Something went wrong with that request. Please try again.