2012-04-06 21 views
0

我的任務是統一具有不同數據庫的HTML表格的統一日期格式。使用SQL過程不是一種選擇。已知的真相是TBODY中的單元格將被包含在一個鏈接中的純文本或純文本。是否有更有效的方式來正則表達式匹配/替換HTML表格中的日期?

我寫了一個做這項工作的jQuery插件,但我想知道是否有意義做innerHTML與通過每個TD循環。

原來的插件:

$.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); 
} 

原執行:

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

innerHTML的實現:

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

這工作,雖然我還沒有測試的innerHTML有多大可能在它失敗之前,準備好後備步驟...

$.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); 
} 
+0

可以移動'td'選擇和循環到插件不改變您的訪問數據,給您「理想的實現」 – Mathletics 2012-04-06 18:50:13

+0

@Mathletics的方法,我其實是試圖避免循環,例如我已經在非表上使用這個,比如數據定義列表。 我的邏輯思考如果1000個日期,但只有25個獨特的日期,對innterHTML做一個正則表達式會更有意義。 但是當我嘗試:這,myregex根本不匹配 – PDA 2012-04-07 13:57:02

+0

添加失敗的實現,失敗,因爲永遠不會返回一個匹配,只是返回有較少換行符的innerHTML。 – PDA 2012-04-07 14:11:15

回答

1

下面是我想到的。爲了理解我是如何得出以下結論的,請閱讀該問題下的評論。

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/