Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #21115

Re: Recommendation for new RegExp (Array-extra-like) methods

Path csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!newsfeed.fsmpi.rwth-aachen.de!uucp.gnuu.de!newsfeed.arcor.de!newsspool2.arcor-online.net!news.arcor.de.POSTED!not-for-mail
Content-Type text/plain; charset="UTF-8"
Message-ID <3573991.qt74eh6WeI@PointedEars.de> (permalink)
From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Reply-To Thomas 'PointedEars' Lahn <usenet@PointedEars.de>
Organization PointedEars Software (PES)
Date Fri, 30 Aug 2013 16:00:57 +0200
User-Agent KNode/4.10.5
Content-Transfer-Encoding 8Bit
X-Face %i>XG-yXR'\"2P/C_aO%~;2o~?g0pPKmbOw^=NT`tprDEf++D.m7"}HW6.#=U:?2GGctkL,f89@H46O$ASoW&?s}.k+&.<b';Md8`dH6iqhT)6C^.Px|[=M@7=Ik[_w<%n1Up"LPQNu2m8|L!/3iby{-]A+#YE}Kl{Cw$\U!kD%K}\2jz"QQP6Uqr],./"?;=4v
Face iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEXTxa4RFk5dUWANED8PFEfy7+MGBiW+n3ZNF/QuAAACaElEQVQ4jVXUwVOcMBQG8Dc7Rc4PUntdWV2uxjDpGaGeozOp1woar4jd5t/v9wLstMwsA/ntlxdCAgUc1hjTc9/JCZfGoo3wG3HdmdAWrIJRHe7GM/TmpY5VFefuVcAkkPbLIaN8rmPmjloyZxgyR3GuJ4K0AGtJ2htz8o7yqikm759fldQXaMpbDzjKAG+8v+AugVTOPO5DOjLvGtUYQwh0CPjnVMyGd+8/GfUB5nLKJDD2aLDh5HYyMDJGDwQIo2ZmZcKbowNmAdB/AzyFhrmF2MHRb0QJJfaAnwGB6orZhoykLzJtGwF/xpYxI1dswomiUj3gTuAIqCn/4C7cULwGNBtwMTk3Y4LfKB5YUaOKBKYtpplm7u0vip8tU1NWWyI/7XdcSuIDoMt6rVHMWT0DbjHPGqDqZVSa6zleLcUTcIKLoMv3ueJluALtAo9B302zPPlrtiVScRdCjXvVh3e3JpYa/jjkuC9N+LrBMlz/eAN4eQijX2EdLo6c5tGGHwLyHFtXk89dDGHwCVhG9T0S/j55AhRZgkMCmUQXJ49TnS1wnQDvw0eAh9ICeMmEFbCnPMFzjAvsWoEWEFdYEx+S0MoUZ1gT1wId8+AF3Bl2OoEu906AUHx5VLw/gXYg/x84loOah/2UYNrgiwSwGO7RfUzVBbx/kgpckumGOi6QirtD6gkLTitbnxNol47S2jVc2vsN5kPqaAHT8uUdAJM4v/DanjYOwmUjWznGfwB7sGtAtor5BgofDuzaRj4kSQAqDakTsKORa3Q3xKi3gE1fhl71KRMqrdZ2AWNNg/YOhQyrVBnb+i+nEg4bsDA+egAAAABJRU5ErkJggg==
Subject Re: Recommendation for new RegExp (Array-extra-like) methods
Newsgroups comp.lang.javascript
References <ac07e89f-90ee-4b6d-a524-5adfadd0cb94@googlegroups.com>
MIME-Version 1.0
Lines 173
NNTP-Posting-Date 30 Aug 2013 16:01:09 CEST
NNTP-Posting-Host 8863c66d.newsspool2.arcor-online.net
X-Trace DXC=jmRD`?hO4IDA<A_d>@P]\DA9EHlD;3YcB4Fo<]lROoRA8kF<OcfhCOKE[fcFYNkLVHDZm8W4\YJNLb@mF9jNikdEDZIgZChmYcKS2\jWhg=gUJ
X-Complaints-To usenet-abuse@arcor.de
Xref csiph.com comp.lang.javascript:21115

Show key headers only | View raw


brettz9@gmail.com wrote:

> I'd be interested to see a way to get over the requirement for writing
> patterns like this:
> 
>     while ((matches = regex.exec(str)) !== null) {

Why, and what is the use-case for your proposal?
 
> I envisioned solving this through an API that could work like this:
> 
> (/^(.*?): (.*)$/m).forEach('key1: val1\nkey2: key2',

Whereas your RegExp.prototype.forEach() is:

| function _mixinRegex (regex, newFlags, newLastIndex) {
|         newLastIndex = newLastIndex === undefined ? regex.lastIndex : 
| newLastIndex;

“undefined” is not read-only in less recent implementations.  Use the 
“typeof” operator instead.

|         newFlags = newFlags || '';

See below.

|         regex = new RegExp(
|             regex.source,
|             (newFlags.indexOf('g') > -1 ? 'g' : regex.global ? 'g' : '') +
|                 (newFlags.indexOf('i') > -1 ? 'i' : regex.ignoreCase ? 'i' 
| : '') +
|                 (newFlags.indexOf('m') > -1 ? 'm' : regex.multiline ? 'm' 
| : '') +
|                 (newFlags.indexOf('y') > -1 ? 'y' : regex.sticky ? 'y' : 
| '') // Non-standard but harmless if already being used
|         );
|         regex.lastIndex = newLastIndex;
|         return regex;
|     }
| 
| RegExp.prototype.forEach = function (str, cb, thisObj) {
|     var matches, n0, i = 0, regex = _mixinRegex(this, 'g');
|     thisObj = thisObj || null;

Should be

  if (typeof thisObj == "undefined")
  {
    thisObj = null;
  }

|     while ((matches = regex.exec(str)) !== null) {
|         n0 = matches.splice(0, 1);
|         cb.apply(thisObj, matches.concat(i++, n0));
|     }
| };

As you are wrapping RegExp.prototype.exec(), you have to create a new RegExp 
instance with _mixinRegx() in order to prevent this from running forever.  
Because you cannot rely on the global modifier being set on the “this” 
value, and you cannot set it afterwards (the “global” property is read-only, 
a poor design choice in ES, IMHO).  So on *each* call of your 
RegExp.prototype.forEach() there is yet another object created, and all the 
property fixes required then are performed, needlessly.

| function (key, val, i, n0) {
|     document.writeln('key is ' + key + ', value is ' + val + ', and the
|     iteration count is ' + i + '<br>');
| });
| 
| I have this and other such Array-extra-like methods added to
| RegExp.prototype at https://gist.github.com/brettz9/6366721 (live at
| http://brett-zamir.me/tests/proposal-regexp-extensions.html ) as a kind of
| proof-of-concept.

This is _not_ the Web.  It would have been better had you also posted some 
code here.
 
> Might something like this that makes global exec iteration more functional
> be possible as a new addition to the next ECMAScript standard?

Possible, yes; likely, no.  Consider that function calls are among the most 
expensive constructs, and there is no reason why a second RegExp instance is 
necessary here other than syntactic sugar.  [I think introducing 
Array.prototype.forEach() was a mistake to begin with.  It would have been 
better to adopt E4X's “for each”.  But when you have John Resig of all 
people as “JavaScript Evangelist” at Mozilla, what do you expect?  jQuery is 
strewn with inefficiencies like this, and so is all jQuery-based code.]

You might instead find my jsx.regexp.RegExp useful, which among other 
features allows you to name subpatterns and access by that name the 
corresponding matches:

  /* ?<Perl> style; also supports ?'Perl' style and ?P<ython> style */
  var regex = new jsx.regexp.RegExp("^(?<first>.+?): (?<second>.+)$", "mg"),
      str = "key1: val1\nkey2: key2",
      match;

  while ((match = regex.exec(str)))
  {
    console.log(match.groups["first"], match.groups["second"]);
    console.log(match[1], match[2]);
  }

“regex” holds an augmented RegExp instance then, whose inherited exec() 
method has been overridden in the instance to return an augmented array-like 
object if necessary (otherwise just the inherited method is called, and its 
return value returned):

      /**
       * @function
       */
      exec: (function () {
        var rx2;

        /**
         * @param {string} s
         * @param {jsx.regexp.RegExp} rx
         *   Instance to be tested
         * @return {boolean}
         *   <code>true</code> if <var>rx</var> has been constructed
         *   using this constructor, <code>false</code> otherwise.
         */
        function _exec (s, rx)
        {
          /* NOTE: Use passed expression only when called statically */
          if (_getClass(this) == "RegExp")
          {
            rx = this;
          }

          rx._realExec = (rx._oldExec || rx.exec);

          var matches = rx._realExec(s);

          if (matches && _RegExp2.isInstance(rx))
          {
            matches.groups = _getDataObject();

            if (rx.unicodeMode && !rx2)
            {
              rx2 = new _RegExp2("^\\W+", "u");
            }

            for (var i = 0, len = matches.length; i < len; ++i)
            {
              /* Trim leading \b matches */
              var patternGroup = rx._patternGroups[i];
              if (rx.unicodeMode
                  && patternGroup
                  && patternGroup.match(
                       /^(\((\?P?(<([^>]+)>|'([^']+)'))?)*\\b/))
              {
                matches[i] = matches[i].replace(rx2, "");
              }

              matches.groups[rx.groups[i] || i] = matches[i];
            }
          }

          return matches;
        }

        return _exec;
      }()),

See <http://PointedEars.de/scripts/test/regexp> for more.

-- 
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Back to comp.lang.javascript | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Recommendation for new RegExp (Array-extra-like) methods brettz9@gmail.com - 2013-08-28 07:51 -0700
  Re: Recommendation for new RegExp (Array-extra-like) methods Andreas Bergmaier <andber93@web.de> - 2013-08-28 17:16 +0200
    Re: Recommendation for new RegExp (Array-extra-like) methods brettz9@gmail.com - 2013-08-28 08:21 -0700
      Recommendation for array-like methods on Iterator; Was Re: Recommendation for new RegExp (Array-extra-like) methods brettz9@gmail.com - 2013-08-28 16:30 -0700
  Re: Recommendation for new RegExp (Array-extra-like) methods Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-08-30 16:00 +0200
    Re: Recommendation for new RegExp (Array-extra-like) methods Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-09-01 15:25 +0200

csiph-web