2018年12月1日

@match マッチパターンの書き方


ブラウザ拡張機能で対象のURLを指定するときに使うマッチパターンの書き方をメモメモ…



GreasemonkeyやTampermonkeyといった拡張機能向けのスクリプトを書く場合、メタデータブロック内で@matchを使うと「どのページで実行するか」を指定することができます。たとえばこんな感じです。

// ==UserScript==
// @match    https://*.wikipedia.org/*
// ==/UserScript==

この書き方は「マッチパターン」と呼ばれる記法で、URLと * の記号を組み合わせてマッチするURLを表します。書き方自体は単純なのですが、知らないとちょっとハマる可能性があるので一応まとめておきます。特に「〇〇〇」は不正な @match パターンです: Error: @match: Could not parse the pattern: 〇〇〇というようなエラーが出てスクリプトの保存ができないときなどにはチェックしてみてください。

マッチパターンの基本

ポイント
  • @include や @exclude と違い正規表現は使えない
  • scheme, host, path の3つの部分から成り立っている

まず、大前提として押さえておくべきなのは、基本的に@matchでは正規表現が使えないということです。「いや当たり前じゃん!」と思うかもしれませんが、@includeや@excludeでは正規表現が普通に使えるので、自分のようなスクリプト初心者は混乱してしまいがちです。さらにワイルドカードである * の記号の使い方も @include / @exclude とは少し違います。このあたりの紛らわしさのせいか、たま~に書き方をミスっているスクリプトを見かけます。

マッチパターンの基本構造はこうです。
scheme://hostpath
URLをschemeとhostとpathという3つの部分に分けて指定します。たとえばこのページのURLの場合は
https://sleepygamersmemo.blogspot.com/2018/12/match-patterns.html
こうなります。httpsがscheme、そのあとのホスト名やドメイン名がhost、最後の"/"以下の部分がpathです。

Scheme

scheme(スキーム)というのはURLの先頭部分("://"の前)にあたる文字列です。「どういうルールで処理を行うか」を決める箇所ですね。
ポイント
  • http, https, file, ftp, * のどれかを指定する
  • ワイルドカード * は「http か https のどちらか」という意味

schemeには"http"、"https"、"file"、"ftp"またはワイルドカードである * のいずれかひとつを指定します。httpとhttpsはもはやお馴染みですね。fileはローカルファイルにアクセスするときに使います。たとえばPCに保存されている文章とか画像とかのファイルをブラウザで開いてみるとアドレス部分が file://~ になっているはずです。ftpはあまり見かけないかもしれません。ftpというプロトコル自体がかなり古く、セキュリティ面でも問題があるという理由からChromeやFirefoxはサポートを打ち切るかも…なんていう記事も出ていました。

たとえばhttpsスキームを指定する場合は次の例のようになります。
@match     https://sleepygamersmemo.blogspot.com/2018/12/
一方、「httpに"s"がつく場合もつかない場合も」という意味で
@match     http*://sleepygamersmemo.blogspot.com/2018/12/
という書き方はマッチパターンの形式としては間違いです。ワイルドカード(*記号)は単独でしか使えません。「httpかhttps」という指定をしたい場合は次のように書きます。
@match     *://sleepygamersmemo.blogspot.com/2018/12/
* は「http https file ftp のうちどれでも」という意味になると思いがちですが、実は違います。 * だけの指定は「http か https のどちらかひとつ」を意味します。したがって上の例の場合は http://sleepygamersmemo.blogspot.com/2018/12/ か https://sleepygamersmemo.blogspot.com/2018/12/ のどちらかのURLにマッチします。file://~ や ftp://~ にはマッチしません。

Host

host(ホスト)部分です。ワイルドカード(*記号)の使い方に少し注意が必要です。
ポイント
  • ワイルドカード * は先頭にしか使用できない
  • * のあとに文字列が続く場合は * の直後に . が必要

…と言われてもなんのこっちゃよく分からないので、例を見てみましょう。まずは正しい例です。
@match     https://sleepygamersmemo.blogspot.com/2018/12/

@match     https://*/2018/12/

@match     https://*.blogspot.com/2018/12/
1つ目は * を使わず指定しています。これはもちろんOK。2つ目はhost部分が丸ごと * になっている例で「schemeとpathさえ一致していればホスト名とかドメイン名とかは何でもいい」というときに使います。これもOKです。3つ目は「ドメインの先頭部分は何でもいいけど最後にblogspot.comがつくものだけ」を表します。いずれの例も * の記号を使う場合は先頭で、かつそのあとに文字列が続く場合は "*.~" という形になっていますね。

次はダメな例です。
@match     https://sleepygamersmemo.*.com/2018/12/

@match     https://*memo.blogspot.com/2018/12/
1つ目は * がhost部分の先頭に来ていないので間違い。2つ目は * がちゃんと先頭に来ているものの、その直後に . ではなく普通の文字が来ちゃってるのでアウトです。

なお、schemeで "file" を指定した場合にかぎり、host部分はなくてもOKということになっています。まあ通常、ローカルのファイルにアクセスするとき使うのは"localhost"や"127.0.0.1"といったホスト名やIPアドレスくらいで、それ以外に特別なホスト名とかドメイン名を指定する必要はないですからね…。

Path

最後はpath(パス)部分について説明します。ルール自体はいたってシンプルです。
ポイント
  • 必ず / からはじめる
  • ワイルドカード * の位置や数は自由

要は"/"が最初にありさえすればあとは何でもOKというゆる~い規則なのですが、意外とここでひっかかることも多いです。たとえば、次の書き方は間違っています。
@match     https://sleepygamersmemo.blogspot.com
正しくは
@match     https://sleepygamersmemo.blogspot.com/
pathは必ず / から始めないといけないので、host部分のあとに / をつけ忘れると「pathがない!」とみなされます。注意しましょう。下記はすべて正しい例です。
@match     https://sleepygamersmemo.blogspot.com/2018/12/*

@match     https://sleepygamersmemo.blogspot.com/*/12/*

@match     https://sleepygamersmemo.blogspot.com/*/*/match-patterns.html

@match     *://*/*patterns*

最初が / からはじまってさえいれば * の個数に制限はありません。4つ目の例は「path部分にpatternsという文字列が含まれているWebページ」すべてにマッチします。

マッチパターンクイズ

マッチパターンの形式についての説明は以上です!ふぇ~長かった~!…では、最後にちょっとしたクイズを出題してみます。かなり難しいので上の説明を読み返しつつよ~く考えてから答えてください。マッチパターン、というかURL(URI)の規則を知っていればサクッと答えられるかもしれません。

 問題:このマッチパターンの指定は有効でしょうか?無効でしょうか?また、その理由は?
@match     file://*
答えを表示

無効です。pathの書き方が間違っています。
順番に見ていきましょう。scheme部分はfileが指定されていて、特に問題ありません。次のhost部分ですが、fileスキームを指定した場合にはhostの記述を省略できるのでした(上のHostの項目を参照)。したがって、host部分は書かなくても問題ありません。では、最後のpath部分はどうでしょう。pathの規則は「必ず / からはじめる」でした。ここに書かれているpathは * だけなので、このルールを無視しています!正しくは
@match     file:///*
こうです。file:// のあとに /* というpathを指定して、スラッシュが3つ並びます。これで「fileスキーム(ローカルファイル)であれば何にでもマッチする」という意味の有効な書き方になるわけです。


おわりに

マッチパターンは正規表現のように細かいルールを指定できるわけではありません。特にホスト名やドメイン名で細かく場合分けしたいときには、@matchではなく@includeや@excludeを使うことになると思います。ただ、制限が厳しく、パターンが少ないということは、正規表現で書くよりも安全で高速に処理できるということでもあります。メリット、デメリットを理解して使い分けたいですね!

参考にしたページ
https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/Match_patterns
https://developer.chrome.com/extensions/match_patterns

0 件のコメント:

コメントを投稿