[js] 正規表現で拡張子・スキーム・ドメインを一括マッチング

アンカーのhrefに含まれる拡張子やスキームに応じたアイコンを表示するっていうのはCSSでよくあるけど、
ドメインに応じてfaviconと同じアイコン表示するのは見たことがない。

どこのサイトか判別するなら大体こんなパターンが考えられる:

  • www.sitename.com … 真ん中にサイト名
  • sitename.com … 先頭にサイト名
  • service.sitename.co.jp … サービス名+サイト名
  • site.name … ドット無くすとサイト名

その理屈をjavascriptの正規表現でやっつけてみたのが次のソースです。

var TextlinksAddClass = function(target,title){
  this.target = target || document;
  this.title = title;
  
  this.start = function(){
    var anc = this.target.getElementsByTagName("a");
    for(i=0; i<anc.length; i++){
      this.setClass(anc&#91;i&#93;,anc&#91;i&#93;.href);
    }
  };
  
  this.setClass = function(a,href){
    //&#91;all,protocol,domain,extention&#93;
    var matches = href.match(/^(?:(&#91;^\:\/\?#&#93;+)\:)?(?:\/\/(?:&#91;\w\d&#93;+\.)?(&#91;^\/\.#=&&#93;+)\.(?:&#91;^\.\/&#93;+)(?:\.&#91;^\/\?#\.&#93;+)*)?(?:(?:&#91;^\?#&#93;)*)(?:\?(?:&#91;^#&#93;*))?(?:#(?:.*\.(\w+)))?/i);
    var class = this._getClass(matches&#91;1&#93;,matches&#91;2&#93;,matches&#91;3&#93;);
    a.className = (a.className? a.className+' ':'')+class;
    
    if(this.title) a.title = class;
    
  };
  
  this._getClass = function(p,d,e){
   if(p=="mailto"||p=="callto"||p=="msnim"||p=="xmpp"||p=="aim"||p=="icq"||p=="skype"||p=="gg"||p=="https"){
     return p;
   }else if(e){
     return e;
   }else if(d){
     return d;
   }
  };
  
  this.start();

}&#91;/js&#93;

<a href="http://jsdo.it/Tenderfeel/lVtC">View Demo &raquo;</a>

del.icio.usみたいなドット無くすとサイト名になるものは判別してない。

上記はアンカーにclassとtitleを付与するものですが、改変して
createElement("img")やstyle.backgroundでclass+'.png'とかすれば自動的にアイコンの挿入が出来る。
アンテナサイトとかで使えるかも。
<span id="more-878"></span>

<h2>正規表現を分割してみる</h2>

全文:

/^(?:([^\:\/\?#]+)\:)?(?:\/\/(?:[\w\d]+\.)?([^\/\.#=&]+)\.(?:[^\.\/]+)(?:\.[^\/\?#\.]+)*)?(?:(?:[^\?#])*)(?:\?(?:[^#]*))?(?:#(?:.*\.(\w+)))?/i
  1. ^(?:([^\:\/\?#]+)\:)?
    http:まで
  2. (?:\/\/(?:[\w\d]+\.)?([^\/\.#=&]+)\.(?:[^\.\/]+)(?:\.[^\/\?#\.]+)*)?
    ドメイン
  3. (?:(?:[^\?#])*)
    ドメイン~?の手前
  4. (?:\?(?:[^#]*))?
    ?以下~#の手前
  5. (?:#(?:.*\.(\w+)))?
    #以下と拡張子

?:は記憶しない指定なので消せばマッチした部分が取り出せる。

参考にした:Uniform Resource Identifier (URI): Generic Syntax

Leave a Comment.