DanLevy.net

ゼロから正規表現ヒーローへ

単一正規表現で URL 風文字列を抽出・解析

目次

TL;DR: まずは 120 バイト以上の正規表現 を確認してください。

🚀 イントロダクション

生テキストから URL を抽出する作業は、時に手間のかかるモグラ叩きゲームのように感じられます。句読点や丸括弧で囲まれた文字列、曖昧なフォーマットがすべて絡み合い、抽出を妨げます。ウェブスクレイパー、データ分析ツール、チャットアプリのいずれを構築していても、正確な URL 抽出は必須です。

この投稿では、柔軟な 2 段階アプローチで問題に正面から取り組みます。まず 潜在的な URL らしさを持つ文字列をすべて捕捉 し、その後で検証を別プロセスで行うことが目標です。

💡 注: このパターンは URL の 検証 ではありません!句読点や誤字に対して意図的に寛容に設計されています。

🔍 目的: テキストから URL を抽出する

生テキストから URL を抽出する際は、2 段階の手法が有効です。

  1. URL らしいものはすべて捕捉: 幅広く網を張り、URL になり得る 文字列をすべて取得します。ここで「120 バイト以上の正規表現」が活躍します。
  2. 検証: 捕捉した候補に対して、二次チェック(例: DNS 解決、既知ドメインとの比較)を行い、無効なエントリを除去します。

課題の可視化

extractparse という用語はしばしば同義に扱われますが、実際には別々のプロセスを指します。URL を 抽出 するとは、テキスト全体から潜在的な URL を検出し捕捉することです。一方、パース するとは、取得した URL を構成要素に分解することを意味します。

パース、すなわち「URL の各部品」について言及するときは、以下のコンポーネントを指しています。

すべての URL が持つ 5 つのパート
URL anatomy, visualized

RegEx101 のサブストリングマッチングのスクリーンショットを見る

正規表現の詳細に入る前に、視覚的ツールでパターンがどれだけ多くのマッチを捕捉できるか確認しましょう。

RegEx101.com を使って複数行マッチを可視化
Preview 'bulk' multi-line matches

120 バイト超の正規表現

以下は URL を一括で抽出・パースできるよう設計された、コンパクトな正規表現です。さまざまなプロトコル、ドメイン、パス、そしてオプションのクエリ/フラグメント部をサポートします。

心配しないでください—段階的に分解していきます!

120+ Byte URL Regex
const urlRegex = /([-.a-z0-9]+:\/{1,3})([^-\/\.[\](|)\s?][^`\/\s\]?]+)([-_a-z0-9!@$%^&*()=+;/~\.]*)[?]?([^#\s`?]*)[#]?([^#\s'"`\.,!]*)/gi;
// Compatibility: ES5+
// 同じパターンを可読性向上のため改行で分割:
([-.a-z0-9]+:\/{1,3})
([^-\/\.[\](|)\s?][^`\/\s\]?]+)
([-_a-z0-9!@$%^&*()=+;/~\.]*)
[?]?([^#\s`?]*)
[#]?([^#\s'"`\.,!]*)
これまでに遭遇した(または自作した)最もワイルドな正規表現を、コメント欄で共有してください! 🚀

🧩 ステップバイステップで分解する

正規表現を構成要素に分解して、動作を確認しましょう。

1. プロトコル (グループ 1): ([-.a-z0-9]+:/{1,3})

2. ドメイン (グループ 2): ([^-/.[](|)s?][^`/s]?]+)

3. パス (グループ 3): ([-_a-z0-9!@$%^&*()=+;/~\.]*)

4. クエリ (グループ 4): [?]?([^#\s`?]*)

5. フラグメント (グループ 5): [#]?([^#\s’”`.,!]*)

🛠️ パース例

以下は、この巨大な正規表現を JavaScript で実際に使う例です。

☑️ 次のステップ

利用シーンに応じて、この正規表現を微調整したり、追加のバリデーションや後処理を組み込む必要が出てくるでしょう。

プロジェクト別の要件

プロジェクトごとに求められる要件やセキュリティ上の懸念は異なります。

  1. Web Scraping: URL が到達可能で信頼できるかを検証します。
  2. Data Processing: ユーザー生成コンテンツから URL を抽出し、安全性を確保します。
  3. Data Analysis: 研究やマーケティング目的で、重複や無関係なリンクを除外します。
  4. User-facing Applications: チャットアプリやフォーラムで URL を自動的にハイパーリンク化します。

後処理と検証

取得した候補 URL に対して追加チェックを行います:

📝 Summary

半構造化文字列データの抽出は、正規表現の熟練度を最大限に活かす、最も満足感のある作業の一つです。

以下は主要なポイントのまとめです:

これらの手順に従えば、任意の半構造化文字列データを確実に抽出でき、以降の処理や検証の土台が整います。

📚 さらに学ぶ