ぺんちゃん日記

食と歴史と IT と。 Web の旅人ぺんじろうが好奇心赴くままに彷徨います 。

【AutoHotkey】Markdown 形式のテキストから URL を抜き出す

目次


タイトルと URL が Markdown で入っている。

先日遭遇した問題。
Google Chrome 拡張で URL をクリップボードに取得すると Markdown 形式になっている。

その拡張はタイトルと URL を Markdown で取得するものだから当然です。
自分が欲しいのは URL だけだから抜き出したい。


拡張が取得したテキストはこんなフォーマット。

[タイトル](URL)。

つまるところ()の中身を抜き出せばいいんですね。
それは RegExMatchコマンドを使って正規表現でマッチさせれば可能ですね。
ただしタイトルがかっこを含んでいると そこがマッチしてしまうので末尾の) あまり含めてマッチさせるべきです。

なお今回の目的はタイトル& URL の中から URL を取りたいだけなので 本格的な文章を相手にするつもりはありません。

正規表現で苦戦

毎回、正規表現には苦戦します。
悪戦苦闘して出た答えがこんな感じ。

\((http|https)(.*)\)$

正規表現では()の中でマッチした文字列を変数で受け取ることができます。
このため正規表現の中に出現する()は特別な意味があります。
どうやって受け取るかは後回しにして、まずは URL をマッチさせる方法を考えます。


今回 URLを探す ための特徴として使いたいのが()
ところが(は引数を受け取る記号なので文字どおりに書くと期待通りにマッチしてくれません。
正規表現内で(を探したい場合は、エスケープ文字\を直前につけてエスケープします。
括弧の中の文字列を探したいならこんな感じ。

\(.*\)

検索の特徴として URL スキームhttpを含めて精度を補強したいです。
つまり、 (http******)という文字列を探すわけですね。
ただしhttpだけでなく httpsのパターンもあるのでどちらも対応しなければなりません。
A または B と言った複数の条件を書くときは ()中で |で区切ります。
今回の場合はこうなります。

(http|https)

これで http 又は https でマッチします。

その後はどんな文字列でも良いとして、最後に)で終わればよいことにします。
マッチした URL を変数に抜き出したいので、ここでも ()で囲みます。

テキストの 末尾を意味する記号は$です。
つまり、テキストデータで)で終わることを期待しているなら、その正規表現はこうなります。

\)$

ということで、 実際のソースコードはこちら。

    pos := RegExMatch(markdown, "\((http|https)(.*)\)$", str)

ここで後回しにしておいた変数で受け取る方法。
RegExMatchコマンドの第三引数でマッチした文字列を受け取ることができます。
ただし今回は URL を囲んでいる外側の格好まで検索しているので、ここで受け取れる文字列は(url)となってしまいます。
まあ後でかっこを取り除いてしまえば良いのですが、ここはもう少し別の方法でやってみます。

正規表現では()で囲まれた条件にマッチした文字列を受け取れるとは上でも書きましたが、第三引数の後ろに数字をつけた変数名で受け取れます。
今回の場合は第三引数の変数が strなので、 str1、str2、str3という変数名となります。
1度目の()では http 又は https のどちらかを探しているので、 マッチした方がstr1に格納されています。
2番目の()でそれ以降の文字列を探しているので、 http 以降、おそらくは ://hogehoge.com/みたいな文字列はstr2に格納されます。
両者を結合すれば URL になります。

できた。

最終的な関数はこちら。
必ずしも Markdown が渡ってくるとは限らないので、それっぽくないものはそのまま返します。

;Markdown 形式の文字列から URL を抜き出す。

geturlfrommd(markdown){
    ;URL の文字列の末尾に()で挟まれているとする。
    ;正規表現では()を使うと 合致した内容を変数で取得できる。
    pos := RegExMatch(markdown, "\((http|https)(.*)\)$", str)
    if pos > 0
    {
        ;受け取る変数strの中にはマッチした内容全体が入っている。
        ;str1, str2 の中には()で囲まれた中の正規表現に一致した文字列が入る。
        ;str1には http 又は https が、 str2にはそれ以降の URL がマッチしている。
        ;両者を結合すれば正確な URL となる。
        url := str1 . str2
        return url
    }
    ;Markdown ぽくなかったらそのまま返す。
    return markdown
}

yasushiito.hatenablog.com


この記事に登場するAutohotkey スクリプトについて

この記事の中で私が作成したプログラムは、全て自由に使うことができます。
詳しくはこちら