#1591 regex matcher implementation for javascript

jessevdam Wed 27 Jul 2011

I created some code which implements the regexp matcher in javascript

javascript for RegexMatcher

/**
 * RegexMatcher.
 */
fan.sys.RegexMatcher = fan.sys.Obj.$extend(fan.sys.Obj);

//////////////////////////////////////////////////////////////////////////
// Constructor
//////////////////////////////////////////////////////////////////////////

fan.sys.RegexMatcher.prototype.$ctor = function(exp, expg, s) 
{
  this.m_exp = exp;
  this.m_expg = expg;
  this.m_s = s; 
  this.m_match = null;
}
fan.sys.RegexMatcher.prototype.$typeof = function() { return fan.sys.RegexMatcher.$type; }

fan.sys.RegexMatcher.prototype.matches = function() 
{ 
  this.m_match = this.m_exp.exec(this.m_s);
  return this.m_match != null;
}

fan.sys.RegexMatcher.prototype.find = function() 
{ 
  this.m_match = this.expg.exec(this.m_s);
  return this.m_match != null;
}

fan.sys.RegexMatcher.prototype.groupCount = function() 
{ 
  if(this.m_match == null)
    throw fan.sys.Err.make("No match found");
  return this.m_match.length - 1;
}

fan.sys.RegexMatcher.prototype.group = function(group) 
{ 
  if(group < 0 || group > this.groupCount())
    throw fan.sys.IndexErr.make(group);
  return this.m_match[group];
}

fan.sys.RegexMatcher.prototype.start = function(group) 
{
  if(group < 0 || group > this.groupCount())
    throw fan.sys.IndexErr.make(group);
  if(group == 0)
    return this.m_match.index;
  throw fan.sys.Err.make("Not implemented in javascript");
}

java script for Regex.js

/**
 * Regex.
 */
fan.sys.Regex = fan.sys.Obj.$extend(fan.sys.Obj);

//////////////////////////////////////////////////////////////////////////
// Constructor
//////////////////////////////////////////////////////////////////////////

fan.sys.Regex.fromStr = function(pattern)
{
  return new fan.sys.Regex(pattern);
}

fan.sys.Regex.glob = function(pattern)
{
  var s = "";
  for (var i=0; i<pattern.length; ++i)
  {
    var c = pattern.charCodeAt(i);
    if (fan.sys.Int.isAlphaNum(c)) s += String.fromCharCode(c);
    else if (c == 63) s += '.';
    else if (c == 42) s += '.*';
    else s += '\\' + String.fromCharCode(c);
  }
  return new fan.sys.Regex(s);
}

fan.sys.Regex.prototype.$ctor = function(source)
{
  this.m_source = source;
  this.m_regexp = new RegExp(source);
  this.m_regexpg = new RegExp(source,"g");
}

//////////////////////////////////////////////////////////////////////////
// Identity
//////////////////////////////////////////////////////////////////////////

fan.sys.Regex.prototype.equals = function(obj)
{
  if (obj instanceof fan.sys.Regex)
    return obj.m_source == this.m_source;
  else
    return false;
}

fan.sys.Regex.prototype.hash = function() { return fan.sys.Str.hash(this.m_source); }

fan.sys.Regex.prototype.toStr = function() { return this.m_source; }

fan.sys.Regex.prototype.$typeof = function() { return fan.sys.Regex.$type; }

//////////////////////////////////////////////////////////////////////////
// Regular expression
//////////////////////////////////////////////////////////////////////////

fan.sys.Regex.prototype.matches = function(s)
{
  return this.m_regexp.test(s);
}

fan.sys.Regex.prototype.matcher = function(s)
{
  return new fan.sys.RegexMatcher(this.m_regexp,this.m_regexpg,s);
}

fan.sys.Regex.prototype.split = function(s, limit)
{
  if (limit === undefined) limit = 0;

  // TODO FIXIT: limit works very differently in Java
  var re = this.m_regexp;
  var array = (limit === 0) ? s.split(re) : s.split(re, limit);
  return fan.sys.List.make(fan.sys.Str.$type, array);
}

There is no support for the start and end function in javascript, only for the start off group 0

EDIT: Putting the complete code not only the new codes

andy Wed 27 Jul 2011

Great - thanks jessevdam - can you make one change tho (just edit your post - don't need a new reply):

fan.sys.RegexMatcher.prototype.$ctor = function(exp, expg, s) 
{
  this.m_exp = exp;
  this.m_expg = expg;
  this.m_s = s; 
  this.m_match = null;
}

And fix and verify the rest of that class. I'd like to use that convention - all fields should prefix with m_. And then I'll pull this into core.

andy Wed 27 Jul 2011

Tho looks like you are missing some methods on Regex - most importantly fromStr - we'll need to flush all those out as well. Verify you can actually invoke this code from Fantom compiled code.

jessevdam Wed 27 Jul 2011

I put complete code for both, I did run self made test script in the browser chrome. Did yet run the full test from the fantom test suite, as which i will do later.

andy Wed 27 Jul 2011

Awesome - didn't realize I had already stubbed some of that code out - but thanks.

SlimerDude Thu 20 Aug 2015

Investigating Javascript errors in BeanUtils led me here!

Any reason why we still don't have a Javascript version of RegexMatcher? I understand that start() and end() can't be implemented, but it looks like the rest could be, no?

andy Thu 20 Aug 2015

If you want to pull this into a patch and verify test suite - we can merge it in.

SlimerDude Mon 24 Aug 2015

@andy, I've just emailed you the patch. Lemme know if it didn't get through.

andy Tue 25 Aug 2015

Landed - changeset

Thanks @jessevdam and @SlimerDude

Login or Signup to reply.