javascript ブラウザ 判別 クライアント

究極の JavaScript クライアント判別, Version 3.03
JavaScriptによってブラウザのベンダ、バージョン、オペレーティングシステムを判断

ウェブページの作成にあたっては、閲覧者が多くのベンダーによる様々なバージョンのブラウザを使用している可能性を考慮に入れる必要があります。プラグインを必要とするような特定のページ要素が全てのオペレーティングシステムで利用可能ではないかも知れない可能性もまた、考慮に入れる必要があるかも知れません。

www.mozilla-japan.org/docs/web-developer/sniffer/browser_type.html

ここにあるサンプルコードによりブラウザのベンダ、バージョン番号、及びオペレーティングシステムを判断することが出来ます。このコードは次のブラウザでテストされています。Navigator 2, 3, 4、Netscape 6、Internet Explorer 3, 4, 5, 5.5, 6、Opera 3, 4, 5、HotJava 3.0 を Windows 98, Windows NT, Macintosh, RedHat Linux, SunOS5 上で。このコードはJavaScript互換ブラウザの全てのバージョン及びプラットフォームでの互換性があると考えられます。このコードはその名前が "is_" で始まる一連の変数群を生成します。これらの変数はブラウザのベンダ、バージョン番号、JavaScriptバージョン、オペレーティングシステムを示したものとなります。

ブラウザのベンダやバージョンを確認して、最適化したマークアップを動的に生成したり、動的生成ページ或いは使用されているブラウザやバージョン番号に合わせた JavaScript コードを実行する条件分岐をしたりすることが出来ます。

この手法は全てのブラウザでサポートされているわけではない機能を使用したページを作成する上で便利です。例えば、Navigator 4 を使用しているユーザは layer タグを含んだものを表示し、他のユーザは "非レイヤ" 版の同じものを表示することが出来ます。

別の例としては、Navigator 4 と Internet Explorer は同じ Dynamic HTML 機能を異なるオブジェクトやメソッドで実装していることが多くあります。ブラウザベンダを確認の後、使用されたブラウザに適した JavaScript コード分岐を行うことが出来ます。Netscape 6 の Gecko レイアウトエンジンの登場により、初めて W3C 標準の DOM Level1,2 を使用したコードを書けるようになりました。将来的には、全てのユーザエージェントが標準準拠となりブラウザやプラットフォームを確認する必要はなくなることでしょうが、Navigator 4 や IE5 がまだ広く使用されている現状では、スクリプトには常にコード分岐を含めるべきです。

HTMLマークアップの動的生成

ページを多くのブラウザに最適化する場合、ブラウザベンダ及び/或いはバージョンを確認した上で、使用されているブラウザに最適化したHTMLマークアップを動的生成するためにページの body 要素中の script 要素で document.write() 文を使用した方が簡単なことがあります。ベンダやバージョン別の HTML マークアップを動的生成するのに必要なコードの一例を用意しました。このコードは後述するブラウザベンダとバージョンを確認する為の JavaScript コードサンプルによって定義された "is_" 変数を使用します。

注 : Internet Explorer の将来のバージョンで私たちのコードが確実に正しく動作するようにするため、ここでは is_ie5 ではなく is_ie5up 変数を使用しています。しかし、Netscape 6 と MozillaNetscape 4 との互換性がないため、Navigator 4 を確認し、Netscape 6, Mozilla や他の Gecko レイアウトエンジンを搭載したユーザエージェントのために is_gecko を使用するべきです。条件分岐コードを書く場合にはいつも将来のブラウザへの前方互換に気を配るのを忘れないように!!

ブラウザ別 JavaScript コード分岐

これで、あなたのページのコア JavaScript 関数中の必要なところでベンダやバージョン別のコード分岐をすることが出来ます。以下のコード分岐は、特定のブラウザでのみ使用可能なオブジェクト、プロパティ、メソッド、関数を使用します。分岐したコードは、その HTML マークアップが特定のブラウザバージョンでのみ動的に生成される HTML ページ要素もまた使用することが出来ます。

この断片的コードは後述するブラウザベンダとバージョンを確認する為の JavaScript コードサンプルによって定義された "is_" 変数を使用し、条件的に別の分岐コードを評価します。

注 : Internet Explorer の将来のバージョンで私たちのコードが確実に正しく動作するようにするため、ここでは is_ie5 ではなく is_ie5up 変数を使用しています。しかし、Netscape 6 と MozillaNetscape 4 との互換性がないため、Navigator 4 を確認し、Netscape 6, Mozilla や他の Gecko レイアウトエンジンを搭載したユーザエージェントのために is_gecko を使用するべきです。条件分岐コードを書く場合にはいつも将来のブラウザへの前方互換に気を配るのを忘れないように!!
[訳註] 原文では ie4up instead of is_ie4 (is_ie4 ではなく is_ie4up) となっていましたが、明らかに間違いであるために訂正しました。

if (is_gecko)

{

// Gecko レイアウトエンジン搭載のユーザエージェント用の JavaScript をここに

}

else if (is_nav4)

{

// Navigator 4 用の JavaScript をここに

}

else if (is_ie5up)

{

// IE4 以降用の JavaScript をここに

}

else if (is_nav3 || is_opera)

{

// Nav3 と Opera 用の JavaScript をここに

}

else

{

// IE3 と Nav2 用の JavaScript をここに

}

クライアント判断における古典的ミスその1: 将来のバージョンのブラウザのことを考えない

Y2Kバグについて聞いたことがあるはずです。1999年以降の年を扱うように設計されていないコンピューターソフトウェアが2000年にエラーを起こしてしまうというあれです。では、V5.0 バグについて聞いたことはありますか?

V5.0 バグでは、バージョン 4.x 以降のバージョンのブラウザに備えて設計されていない JavaScript コードがエラーを起こしてしまうのです。年が変わっても誤動作しないようにするために 2000 年までにソフトウェアを再確認するべきであるのと丁度同じように、新しいブラウザで誤動作をしないように Internet Explorer 5 や Netscape 6 を使用する前にソフトウェアを見直すべきです。

この V5.0 はごくありふれたミスによって引き起こされ得ます。これらの問題の犠牲になってしまわぬよう、今すぐコードを確認して下さい。・・・

1.コードがヴァージョンN以降のブラウザで動作するなら、== ではなく >= でブラウザバージョンチェックをしていることを確認して下さい。

例えば、Navigator 4 以降と Internet Explorer 4 以降で動作するコードがあるとしましょう。次の2つのクライアント判別の仕方を比較して下さい。・・・

間違った方法 正しい方法
if (is_nav4 || is_ie4) {

/* Nav4+, IE4+ で動作するコード。if節が Nav4 と IE4 の時のみ true を返すので、コードは Netscape 6 や IE5 以降では決して実行されません。おおっと! is_major >= 4 とするべきでしたね。 */
/* [訳註] 原文のまま訳しましたが、"is_major >= 4とするべき"ではなく、"is_nav4up || is_ie4up とするべき"というのが正しいはずです。 */

}
if (is_nav4up || is_ie4up) {

/* Nav4+, IE4+ で動作するコード。if 節は Nav4 以降と IE4 以降で true を返すので、サポートされる全てのブラウザでコードが実行されます。 */

}

後述のコードサンプルによる is_major 変数を使用した例も用意しました。
間違った方法 正しい方法
if (is_major == 4) {

/* Nav4+, IE4+ で動作するコード。if節が Nav4 と IE4 の時のみ true を返すので、コードは Netscape 6 や IE5 以降では決して実行されません。おおっと! is_major >= 4 とするべきでしたね。 */

}
if (is_major >= 4) {

/* Nav4+, IE4+ で動作するコード。if 節は Nav4 以降と IE4 以降で true を返すので、サポートされる全てのブラウザでコードが実行されます。 */

}

2.コードを新しいブラウザや W3C DOM に合わせて更新する必要があるのでしたら、今すぐサポートとバージョンチェックを組み込んで下さい。

Gecko レイアウトエンジンは Netscape 6 と MozillaW3Cドキュメントオブジェクトモデルレベル1 (DOM1) とレベル2 (DOM2) のような主な標準をサポートする初のブラウザとするでしょう。今に至るまで、先進の JavaScript アプリケーションや Dynamic HTML を書きたいと思うウェブ開発者は Navigator 4 DOM と Internet Explorer 4 DOM を使用するほかありませんでした。これらの DOM はいずれも独占的なものであり、W3C DOM 非準拠であり、相互互換性もありません。同じ機能を2つの異なった DOM で開発しデバッグすることの難しさ、苛立ち、手間から、ウェブ開発者達は全てのブラウザベンダが W3C DOM を完全にサポートし、一度書けばどこでも動くようにすることを求めました。

Netscape 6 と Mozilla は少なくともウェブ開発者達の要求する W3C 標準を提供します。W3C DOM の能力とクスプラットフォーム互換性の利点を全て享受するには、アプリケーションがそれをサポートするように改良する必要があります。W3C DOM を学ぶのには少々時間がかかるが、少なくともベンダー非依存、プラットフォーム非依存、アプリケーション非依存のドキュメントオブジェクトモデルについて学んでいるんだということを忘れないように。W3C DOM は21世紀の DOM なのだから。使い方を学ぶことであなたは、以降の生涯ずっと使用できる、現代のウェブサイトデザインと開発技術の最先端に位置することができるでしょう。

あるユーザエージェントが Gecko レイアウトエンジンを搭載しているか判断するためには、ユーザエージェント文字列が "Gecko" を含んでいるか確認すべきです。現在の Mozilla のユーザエージェント文字列規則についてはこのテクニカルノートをご覧下さい。
クライアント判断における古典的ミスその2: オブジェクト判断とクライアント判断を混同する

クライアント判断の有名な方法の一つにオブジェクト判断があります。オブジェクト判断の支持者は、新しいクライアントは絶えず出てくるのだから、クライアントを明確に判断してクライアント専用のオブジェクトとメソッドを使用するよりも、単に必要なオブジェクトが存在するか確認し、存在すれば使えばいいのだと主張します。

この手法は、その論理の極限までつきつめて、全ての個々のオブジェクトとメソッドを使用前に確実にテストする場合に限って上手くいきます。

この手法の問題は、多くの人が次のようなことをしてしまうことです…

* document.all の存在を確認し、存在すれば、IE4 が使用されており document.all それ自体のみならず Internet Explorer の DOM 全てが使用可能だと決めつける。
* document.layers の存在を確認し、存在すれば、Nav4 が使用されており document.layers それ自体のみならず Navigator 4 の DOM 全てが使用可能だと決めつける。

例えば、このような感じです。

間違った方法 正しい方法
if (document.getElementById) {

/* document.getElementById に加えてその他多くの Netscape 6 や W3C DOM1 の機能を、それらのオブジェクトやメソッドも同様にテストせずに使用したコード。しまった!個々のオブジェクトとメソッド使用前に一度確かめなくては。 */

} else if (document.layers) {

/* document.layers に加えてその他多くの Nav4 の機能を、それらのオブジェクトやメソッドも同様にテストせずに使用したコード。しまった! 個々のオブジェクトとメソッド使用前に一度確かめなくては。 */
} else if (document.all) {

/* document.all に加えてその他多くの IE4 の機能を、それらのオブジェクトやメソッドも同様にテストせずに使用したコード。しまった! 個々のオブジェクトとメソッド使用前に一度確かめなくては。 */
} if (document.getElementById) {

/* テストによって存在を確認したのはそれだけなのだから、document.getElementById のみを使用したコード。良いオブジェクト判断コードは個々のオブジェクトとメソッド使用前に一度確認する。 */
} else if (document.layers) {

/* テストによって存在を確認したのはそれだけなのだから、document.layers のみを使用したコード。良いオブジェクト判断コードは個々のオブジェクトとメソッド使用前に一度確認する。 */
} else if (document.all) {

/* テストによって存在を確認したのはそれだけなのだから、document.all のみを使用したコード。良いオブジェクト判断コードは個々のオブジェクトとメソッド使用前に一度確認する。 */
}

左列のコードが問題であるのは、document.all が定義されていても Internet Explorer 4 であるという保証はどこにもなく、document.layers が定義されていても Netscape Navigator 4 であるという保証はどこにもなく、document.getElementById が定義されていても Netscape 6, Mozilla や他の DOM1 準拠ブラウザであるという保証はどこにもないということです。

新しいブラウザは (Opera や iCAT のように) 絶えず出てくるのです。NetscapeMicrosoft のブラウザ以外が Navigator と Internet Explorer の2つの DOM を混合した機能を持つかも知れません。例えば、非NetscapeMicrosoft ブラウザ DOM が document.layers と document.all の両方をサポートし、しかしながらどちらの機能も完全にはサポートしないかも知れません。もし document.all の存在を確認し、そして (document.all が定義されていたら) document.all の他の多くの IE の機能を使用したコードを書けば、そのコードは document.all をサポートするが他の IE の機能をサポートしないブラウザ全てでエラーを起こしてしまうことでしょう。同様に、document.layers の存在を確認し、そして (document.layers が定義されていたら) document.layers の他多くの Navigator 4 の機能を使用したコードを書けば、そのコードは document.layers をサポートするが他の Navigator 4 の機能をサポートしないブラウザ全てでエラーを起こしてしまうことでしょう。

既存のブラウザの新しいバージョンも絶えず出てきます。Netscape 6 や Mozilla は document.getElementById のような DOM1 の機能を完全にサポートしていますが、この機能をサポートする唯一のブラウザではありません。IE5 もまた document.getElementById を実装していますが、他の多くの W3C DOM 機能のサポートが欠けています。この特定のメソッドを判断することで、ブラウザがドキュメントオブジェクトの getElementById をサポートしていることは分かりますが、Netscape 6, Mozilla や IE5 であるかは分からないわけです。

以上による教訓 : 特定のオブジェクトを判断しても、その特定のオブジェクトを判断したに過ぎない。いずれのブラウザであるかは確実には分からない。特定のオブジェクトを判断したことで分かるのは現在のクライアントでその特定のオブジェクトが存在するということに過ぎない。

Internet Explorer の navigator.appVersion に関する変な挙動

Internet Explorer には navigator.appVersion プロパティについて注意すべきおかしなことが2つあります。・・・

* navigator.appVersion プロパティを Internet Explorer 3.0 で調べると、Windowsに於いては Internet Explorer 3.0 は自身が Navigator 2.0 だとして navigator.appVersion プロパティが 2 を返すことが分かります。Macintosh に於いては Internet Explorer 3.0 は自身が Navigator 3.0 だとして navigator.appVersion は 3 を返しますが。
* Internet Explorer 5.0 で navigator.appVersion プロパティ を調べれば、4 を返します。

結果として、後述のサンプルを使用するときは is_major 及び is_minor 変数の値は額面通りの値として受け取ってはいけません。これらの変数はクライアントの報告する appVersion に過ぎず、正確かも知れませんし、正確でないかも知れません。信頼に足るバージョン判断をするには、is_nav6up, is_nav4, is_ie5up, is_ie4 などといった真偽値変数を使用してください。

Ameria Online 4.0 の navigator.userAgent に関する変な挙動

AOL のユーザエージェント文字列は必ず "AOL #.#" という文字列を含んでいます。シャープ記号が 3.0 や 4.0 といったバージョンを表します。これは実際HTTPヘッダで報告されるユーザエージェント文字列に関しては常に成り立ちます。常に "AOL #.#" が含まれるのです。

しかしながら、JavaScript で報告される navigator.userAgent 文字列については、次のような場合 "AOL #.#" がユーザエージェント文字列に含まれないというバグが AOL 4.0 にあります。

* AOL のセッションで最初に開かれたブラウザウィンドウである場合。
* 組み込みブラウザが MSIE 3.x である場合。

このように、navigator.userAgent 文字列の "AOL #.#" を探すことで AOL クライアントを判断しようとするクライアントサイド JavaScript コードは 100% 信頼できるものではありません。今のところ AOL クライアントをクライアントサイド JavaScript で 100% 信頼できる判断ができる対応策は知られていませんので、AOL クライアント判断が必要な場合にで推奨されるのは HTTP ユーザエージェント文字列によるサーバサイドでの判断です。


Netscape 6 の navigator.userAgent に関する変な挙動

Netscape 6 は 6 と呼ばれていますが、ユーザエージェント文字列の含むバージョン番号は 5 であることに注意しなければなりません。そして、このブラウザを判断する場合には is_major == 6 ではなく is_major == 5 として確認しなければなりません。

ブラウザベンダ、バージョン、オペレーティングシステム を判断するJavaScript コード

ブラウザベンダ、バージョン番号、オペレーティングシステムを判断するのに必要な JavaScript コードを用意しました。このコードはブラウザベンダ、バージョン番号、JavaScript バージョン、オペレーティングシステムを示す一連の変数群を生成します。

このコードはJavaScript互換ブラウザの全てのバージョン及びプラットフォームでの互換性があると考えられます。このコードは次のオペレーティングシステムとブラウザでテストされています。・・・

* Windows NT: Navigator 4, Navigator 3, and Navigator 2; Internet Explorer 5; Internet Explorer 3; Opera 3
* Windows 98: Netscape 6;Navigator 4.76; Internet Explorer 4; Internet Explorer 5; Internet Explorer 5.5; Opera 5; HotJava 3
* Macintosh: Navigator 4, Internet Explorer 3.01, Internet Explorer 4.02
* RedHat Linux 6.2: Navigator 4.6; Netscape 6
* SunOS5: Navigator 3


//

あなたのブラウザプロファイル

これはあなたがお使いのブラウザでこのコードを使用した結果です。以下のテキストはご利用のブラウザベンダ、バージョン、オペレーティングシステムJavaScript で判別して動的生成したものです。

元となるデータ
navigator.appName Netscape
navigator.userAgent Mozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP; rv:1.7.10) Gecko/20050717 Firefox/1.0.6
navigator.appVersion 5.0 (Windows; ja-JP)

バージョン番号
major:5
minor:5

ブラウザバージョン
nav:true
nav2:false
nav3:false
nav4:false
nav4up:true
nav6:true
nav6up:true
gecko:true
navonly:false

ie:false
ie3:false
ie4:false
ie4up:false
ie5:false
ie5up:false
ie5_5:false
ie5_5up:false
ie6:false
ie6up:false

aol:false
aol3:false
aol4:false
aol5:false
aol6:false

opera:false
opera2:false
opera3:false
opera4:false
opera5:false
opera5up:false

webtv:false

hotjava:false
hotjava3:false
hotjava3up:false

AOL TV(TVNavigator):false

JavaScript バージョン
js:1.5

OS
win:true
win16:false
win31:false
win32:true
win95:false
win98:false
winme:false
winnt:true
win2k:false

os2:false

mac:false
mac68k:false
macppc:false

unix:false
sun:false
sun4:false
sun5:false
suni86:false
irix:false
irix5:false
irix6:false
hpux:false
hpux9:false
hpux10:false
aix:false
aix1:false
aix2:false
aix3:false
aix4:false
linux:false
sco:false
unixware:false
mpras:false
reliant:false
dec:false
sinix:false
bsd:false
freebsd:false

vms:false

で、何故オブジェクト指向にしないのかって?

以下のようにもう少し美しい手法ではなく、どうして似たような名前の変数群を生成するのか疑問なのでしょう。・・・

function Is ()

{ var agt=navigator.userAgent.toLowerCase();


this.major = parseInt(navigator.appVersion);


this.minor = parseFloat(navigator.appVersion);


this.nav = *1;

this.nav3 = (this.nav && (this.major == 3));



・・・ 中略 ・・・

this.vms = (agt.indexOf("vax")!=-1) || (agt.indexOf("openvms")!=-1);

}


var is = new Is();


if (is.nav) { ・・・ navigator 用コードをここに ・・・ }

else if (is.ie) { ・・・ explorer 用コードをここに ・・・ }

簡単なことです。"is" オブジェクトに纏めることでカプセル化した変数を提供するこのコードの方が遙かに美しいですが、MacintoshInternet Explorer 3 では破綻します。Mac の IE3 で "is" オブジェクトを生成する場合、最初の読み込み時は上手くコードが動作しますが、ページをリロードすればブラウザがクラッシュします。Mac の IE3 でのこの問題を回避するため、"is" オブジェクトは生成しないのです。その代わり、同じような名前の真偽値変数群を生成します。これは汚いですが、Macintosh IE3 での JScript のこのバグに対応させる代償なのです。

もう一つ考えられる対策は全てのブラウザでオブジェクト指向のコードを使用するが、Mac の IE3 ではオブジェクト指向コードの実装を避けるようにするチェックで囲うことです。これによりオブジェクト指向の設計を保ちますが、is オブジェクトを参照する度に if (!isIE3Mac && is_nav4up) といった追加の真偽判断が必要となります。こういった追加の真偽判断は面倒なので、諦めて上のような単純な非オブジェクト指向としたのです。しかしながら、オブジェクト指向の手法が好きでしたら、Macでの安全確認付オブジェクト指向クライアント判別を用意していますのでご利用下さい。最後に、Mac の IE3 をサポートする必要がないのでしたら、オブジェクト指向コードを用いつつ、Macでの安全確認を省くことも出来ます。

他のブラウザ判別に関する情報源
BrowserSpy
userAgent Strings on Browsers Based on Mozilla and Applications That Embed Gecko Layout Engine

更に詳しく
JavaScript Known Bug List
Sample Code Area
Articles
JavaScript Course
Other JavaScript Resources
JavaScript Documentation
What's New in JavaScript for Navigator 4.0
JavaScript Scripting Tools

VIEW SOURCE の記事
Beyond Data Basics: Writing JavaScript Database Applications, Part 1
Beyond Data Basics: Writing JavaScript Database Applications, Part 2
JavaScript Date Object Techniques
Scripting Layer Effects and Transitions
Detecting a JavaScript Client
Bringing Images to Life with JavaScript

会員情報源
JavaScript Newsgroups
JavaScript FAQ

このテクニカルノートにコメントがあるのですか?

JavaScript、Dynamic HTML や その他の Netscape の技術や製品に関してテクニカルサポートやその他の支援が欲しいのでしたら、サポートエリアを訪れてください。このコードサンプルに対するコメントや提案はxbrowser@netscape.comにメールを送って下さい。問題を報告してくださったり質問をされる場合、以下の情報を含んでいることをご確認下さい。・・・

* ハードウェアプラットフォームと OS のバージョン (例: iMac with MacOS 8.5)
* ブラウザのベンダとバージョン番号 (例: Navigator 4.08)
* 問題の詳細
* 上の "あなたのブラウザプロファイル" 章すべてを、問題のあるというブラウザで表示したもののコピー。

[訳註] 勿論ですが、英語でお願いします。(^^;

提案が多数あるので私たちは通常は個別に応答することができませんが、送られたコメントはこのサイトの将来のコンテンツ作成に取り入れていきます。

Sun-Netscapeアライアンスの成果についての最新の技術情報を得るには、developer.iplanet.com へどうぞ。

更なるインターネット開発の情報源を得るには、Netscape TechSearch をお試し下さい。

ブラウザの判別

使用されているブラウザは Netscape です。
ブラウザの判別

実行結果: 5.0 (Windows; ja-JP)
ブラウザの判別

実行結果: Mozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP; rv:1.7.10) Gecko/20050717 Firefox/1.0.6

Internet Explorer (IE) の場合 Qxxxxxx や Txxxxxx(xxxxxx は数字)が表示されることがありますが、これは IE の修正パッチを入れると表示されます。
ブラウザの判別(詳細)

Mozilla Firefox 1.0.6

検索対象文字列.match(/←始まり 正規表現 終わり→/); として/ 〜〜 / 内に正規表現を使用してそれぞれのブラウザの名前とバージョンを検索して取得します。正規表現内に「$ ( ) * + - . / ? @ [ ] \ ^ { } |」を文字列として使用する場合は、これら文字の前にバックスラッシュ「\」を付けてエスケープさせます。なお、「-」は一番最初か最後に使用する場合のみエスケープ不要です。

正規表現にマッチした文字列や数値をあとから参照するには、参照したい正規表現を括弧で括ります。この括弧で括った正規表現RegExp.$n で参照することができます。n は正規表現内の n 個目の括弧にマッチした文字列です。

なお、正規表現の拡張構文である (?:pattern) (?=pattern) (?!pattern) は OS の環境(Windows では JScript のバージョンが古いなど)や一部の古いブラウザは対応していない模様です。

Opera の場合は、他のブラウザとして振舞うことが簡単にできますので一番初めにチェックの対象にします。ユーザーエージェントに Opera という文字列があれば、スラッシュか空白文字のあとにバージョンがありますので、(\d\.\d+) として「数値ドット1文字以上の数値」の順番に並んでいる部分を参照します。これは、7.11 や 7.52 のような文字列にマッチします。

Internet Explorer の場合は、MSIE という文字列があるかを判別します。MSIE という文字列があれば、空白文字のあとにバージョンがありますので、(\d\.\d+) として「数値ドット1文字以上の数値」の順番に並んでいる部分を参照します。これは、5.01 や 5.12 や 6.0 のような文字列にマッチします。

Netscape Communicator の場合は、Mozilla/4.5 〜 Mozilla/4.8 があるかを判別します。[5678] は 5 か 6 か 7 か 8 のいずれかにマッチするという意味です。これは [5-8] とすることもできます。最後の \d? は0文字か1文字の数値にマッチするという意味なので、数値があってもなくても良いということになります。よって、4.7 や 4.78 のような文字列にマッチします。

Netscape, Safari の場合は、初めにブラウザ名を判別します。Netscape6? の 6? は先ほどの \d? と同様に 6 があってもなくても良いということです。バージョンを調べるためには ([\.\d]+) として1文字以上のドットか数値が続いている部分を参照します。これは、6.2.3 や 7.01 のような文字列にマッチします。

Mozilla の場合は、Gecko という文字列があるかを判別します。Netscape, Safari にも Gecko という文字列が含まれていますが、上記においてマッチしていますのでここの判別にはかかりません。Mozilla には Firefox(旧Firebird)や Thunderbird(メールソフト)といった種類もありますので判別の対象にします。

この例では、ブラウザを検索して括弧内の正規表現でバージョンを参照して表示します。この方法を用いてブラウザ別に処理を振り分けることも可能ですが、振り分ける項目が多いので、ブラウザ別に振り分けるを参照してください。

以下は各ブラウザのユーザーエージェントの値です。(私が実際使用したブラウザのみ)
Opera (7.52 - Windows 2000)

Opera/7.52 (Windows NT 5.0; U) [ja]
Mozilla/4.78 (Windows NT 5.0; U) Opera 7.52 [ja]
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0) Opera 7.52 [ja]

Internet Explorer (5.01, 6.0 - Windows 2000 / 5.14 - MacOS 9.0.2)

Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)
Mozilla/4.0 (compatible; MSIE 5.14; Mac_PowerPC)
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)

Netscape Communicator (4.78 - Windows 2000)

Mozilla/4.78 [ja] (Windows NT 5.0; U)

Netscape 6 (6.23 - Windows 2000)

Mozilla/5.0 (Windows; U; Windows NT 5.0; ja-JP; rv:0.9.4.1) Gecko/20020508 Netscape6/6.2.3

Netscape 7 (7.1 - Windows 2000)

Mozilla/5.0 (Windows; U; Windows NT 5.0; ja-JP; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)

Mozilla (1.2 - Vine Linux 2.6)

Mozilla/5.0 (X11; U; Linux i686; ja-JP; rv:1.2) Gecko/20030401 for VineLinux 0vl0.26

Mozilla Firefox (1.0 - Vine Linux 3.1)

Mozilla/5.0 (X11; U; Linux i686; ja-JP; rv:1.7.5) Gecko/20041108 Firefox/1.0

*1:agt.indexOf('mozilla')!=-1) && ((agt.indexOf('spoofer')==-1) && (agt.indexOf('compatible') == -1))); this.nav2 = (this.nav && (this.major == 2