Is there a more efficient way to regex match/replace dates in an HTML table?

I've been tasked with unifying date formats of an HTML table that has different databases feeding into it. Utilizing a SQL procedure is not an option. The known truths are the cells in the TBODY will be plain text or plain text wrapped in one link.

I wrote a jQuery plugin that does the job, but I'm wondering if would make sense to do innerHTML versus looping through each TD.

original plugin:

$.fn.reformatAllDates = function () {
  var $txt = $(this).text();

  var reformatDate = function ($str) {
    var $parts = $str.split('/'),
        $year = $parts[2],
        $month = $parts[0],
        $day = $parts[1];
    if ($parts.length === 3) {
      $month = $month.length < 2 ? '0' + $month : $month;
      $day = $day.length < 2 ? '0' + $day : $day;

      //Returns dates in sort friendly format [YYYY-MM-DD]
      return $year + '-' + $month + '-' + $day;
    }
    return $str;
  };

  var $result, $reg = new RegExp(/^\d{1,2}\/\d{1,2}\/\d{4}$/);

  while (($result = $reg.exec($txt)) !== null) {
    var $match = $reg.exec($txt)[0];
    var $newFormat = reformatDate($match);
    $txt = $txt.replace($match, $newFormat);
  }
  return $(this).html($txt);
}

original implementation:

$('table.display tbody tr td').each(function () {
  if ($(this).html().indexOf('href') >= 0)
    $(this).find('a:first').reformatAllDates();
  else
    $(this).reformatAllDates();
});

innerHTML implementation:

$('table.display tbody').reformatAllDates();

This works, though I haven't yet tested how big the innerHTML can be before it fails and prepared the fallback steps in...

$.fn.reformatAllDates = function () {
  var $result, 
      $reg = new RegExp(/\d{1,2}\/\d{1,2}\/\d{4}/),
      $r2 = new RegExp(/[\n\r\f]/g),
      $html = $(this).html();
  $html = $html.replace($r2,'');
  $html = $html.replace($r2,'');

  var reformatDate = function ($str) {
    var $parts = $str.split('/'),
        $year = $parts[2],
        $month = $parts[0],
        $day = $parts[1];
    if ($parts.length === 3) {
      $month = $month.length < 2 ? '0' + $month : $month;
      $day = $day.length < 2 ? '0' + $day : $day;
      return $year + '-' + $month + '-' + $day;
    }
    return $str;
  };

  var $match, $newFormat, $msg;
  while (($result = $reg.exec($html)) !== null) {
    $match = $reg.exec($html)[0];
    $newFormat = reformatDate($match);
    var $re = new RegExp($match,"g");
    $html = $html.replace($re, $newFormat);
  }
  return $(this).html($html);
}

Answers


Below is what I came up with. To understand how I came to the following, read through the comments under the question.

jQuery(document).ready(function($) {
    var reg = new RegExp(/^\d{1,2}\/\d{1,2}\/\d{4}$/);

    $.fn.reformatAllDates = function (subselect) {
        var $this = $(this),
            $nodes,
            $node,
            text,
            matched;

        if (subselect) {
            $nodes = $this.find(subselect);
        } else if ($this.is('table')) {
            $nodes = $this.find('td');
        } else if ($this.is('dl')) {
            $nodes = $this.find('dt, dd');
        } else {
            $nodes = $this.children();
        }

        for (var i = 0, l = $nodes.size(); i < l; i++) {
            $node = $($nodes[i]);
            text = $node.text();
            matched = text.match(/\//g);

            if (matched !== null && matched.length == 2) {
                $node.reformatDate(text);
            }
        }
    };

    $.fn.reformatDate = function(text, parts) {
        var $this = $(this),
            matched,
            year,
            month,
            day;

        if (!parts) {
            text = text ? text : $this.text();
            matched = reg.exec(text);
            parts = matched !== null ? matched[0].split('/') : [];
        }

        if (parts.length === 3) {
            month = parts[0];
            day = parts[1];
            year = parts[2];

            month = month.length < 2 ? '0' + month : month;
            day = day.length < 2 ? '0' + day : day;

            //Returns dates in sort friendly format [YYYY-MM-DD]
            $this.html(year + '-' + month + '-' + day);
        }
    };

    $('#trigger').click(function(){
        $('#tabledata').reformatAllDates();
    });
});

http://jsfiddle.net/userdude/gkeL6/10/


Need Your Help

Behance API var starts with number

php api

at Behance API a get an array of objects that are my projects. But when I print cover object i get this:

Issue on magento installation in xampp localhost

php mysql magento

I install magento on xampp localhost first time, the error occurred when i enter the DB details and click on continue, the error is:

Sharing Data between XIB's

iphone objective-c

I'm following the James Brannan tutorial's, and im trying to share data between some xbis. No luck.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.