URLをリンクに変更する (WebHelpersのauto_link)
マリオカートやり過ぎて目がシバシバしているbonlifeです。この記事を見て、そういうのって色んな人が似たようなことやってるのよね、きっと。と思って少しだけ調べてみました。
正規表現を使ってURLをリンクにする。
それっぽいキーワードで適当に検索したところ、Pylonsで使われているWebHelpersにRailsにインスパイアされた機能があることが判明。
WebHelpersのauto_link_urls
AUTO_LINK_RE = re.compile(r""" ( # leading text <\w+.*?>| # leading HTML tag, or [^=!:'"/]| # leading punctuation, or ^ # beginning of line ) ( (?:https?://)| # protocol spec, or (?:www\.) # www.* ) ( [-\w]+ # subdomain or domain (?:\.[-\w]+)* # remaining subdomains or domain (?::\d+)? # port (?:/(?:(?:[~\w\+%-]|(?:[,.;:][^\s$]))+)?)* # path (?:\?[\w\+%&=.;-]+)? # query string (?:\#[\w\-]*)? # trailing anchor ) ([\.,"'?!;:]|\s|<|$) # trailing text """, re.X)
捕捉しないカッコが出るだけで難しく見えるマジックですね。この正規表現をこんな関数で使う。
def auto_link_urls(text, **href_options): extra_options = tag_options(**href_options) def handle_match(matchobj): all = matchobj.group() a, b, c, d = matchobj.group(1, 2, 3, 4) if re.match(r'<a\s', a, re.I): return all text = b + c if b == "www.": b = "http://www." return '%s<a href="%s%s"%s>%s</a>%s' % (a, b, c, extra_options, text, d) return re.sub(AUTO_LINK_RE, handle_match, text)
<a で始まってたら、処理せずにそのまま返して、www. 始まりだったら http:// をつけるのね。正規表現の h の後にも ? を追加して ttp:// はじまりにも対応したら良いのに。ってこれは日本限定の文化かな。
WebHelpersのauto_link_email_addresses
ちなみにメールアドレス用の正規表現もそれらしい関数に含まれてましたよ。
def auto_link_email_addresses(text): return re.sub(r'([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)', r'<a href="mailto:\1">\1</a>', text)
ふーん。何で \w 使ったり使わなかったりなんだろう。後半部分でも \w 使えますよね。って思って調べてみたら、\w だと _ (アンダースコア)も含んでしまうんですね。だから外してるのか。これくらいがザル過ぎず、複雑になり過ぎない絶妙なラインってことなのかしら。って納得しかけたけど、ローカルパート部分に . (ドット)が2回出てくる?アレレ。 + の次にあるエスケープされていないドットは何なんだろう…。文字クラスの書き方が分からなくなってきましたが、とりあえず保留。