RE:HTMLのhrefパーサ

やさしいt-fridgeが以前に書いたhrefパーサについての返事をくれたので,コードを解析してみます.

以前に僕の書いたコードは

# coding: utf-8
import re

def hrefParser (inStr):
    buff = []
    ro1 = re.compile ("<a.+?href\s*=\s*\"(.*?)\".*?>", re.I)
    ro2 = re.compile ("<a.+?href\s*=\s*\'(.*?)\'.*?>", re.I)

    rs1 = ro1.search (inStr)
    while (rs1):
        buff.append (inStr[rs1.group ().start ():rs1.group ()end()])
        inStr = inStr[:rs1.group ().start ()] + inStr[rs1.group ().end():])
        rs1 = ro1.search (inStr)

    rs2 = ro2.search (inStr)
    while (rs2):
        buff.append (inStr[rs2.group ().start ():rs2.group ()end()])
        inStr = inStr[:rs2.group ().start ()] + inStr[rs2.group ().end():])
        rs2 = ro2.search (inStr)

    return buff

はは,醜い.

で,t-fridgeのコードは

# coding: utf-8
import re

reg = re.compile( r'<a\s+.*href\s*=\s*[\s|\'|"]{0,1}(http://[a-zA-Z\d?*!$&%#@~_=\-/.,;:()]+)[\s|\'|"]{0,1}.*>.*</a>', re.IGNORECASE )
def searchURL(bodystring):
    return = re.findall(reg,bodystring)

おお,短い.

ざっと見てポイントは正規表現findallにあるようですね.

正規表現

まず,僕の無知.

パイプ"|"を使うとキャラクタークラスの中に選択肢を押し込む事が出来る点.

無知でした.

次に,ぼくの想定していたタグの属性の書き方は

なんだけど,t-fridgeの話によると

のような表記も誤りながら認められているらしい.

そのため,[\s|\'|"]{0,1}というパターンになるらしい.

この表現で上記の3つ全てのパターンに対応できる.

findall

で紹介されているように文字列の中から複数のマッチするものをヒットさせることが可能なのがfindall.

無知でした.

まとめ

がんばる.

正規表現は要勉強.たくさんパターンを書こう.



Pythonは本当の始めからやり直したい.

適当にやってるとためだ.

というわけで明日,某所でPython本でもかってこようかな.

初めてのPython 第3版

初めてのPython 第3版