On Tue, 11 Jan 2005 15:26:34 +0900 (JST), Nobuo Yamashita  
<nobsun / sampou.org> wrote:
>> <a href="content.html>
>>
>> のように閉じの抜けた正しくない HTML でもきちんと動作するものが
>
> words で区切っておいて、区切った単語ごとに最初の文字と
> 最後の文字を見て、引用符とか、=とかを解釈しながら、
> 字句分解する必要がありますね。
>
> ただ、well-formed でないようなものを、どのように解釈するかを定式化する
> のは難しそうですねぇ。引用符の閉じ忘れであることをどこで判断するかを決め
> なくてはなりませんね。それに、引用符の開きわすれとか、引用符の不一致とか 
> 
> どうします?

そこまで考えていませんでした。とりあえず上のケースぐらいを想定して、下の
コードで処理していたんですけど。
まず最初に対象性があるかどうかチェックして、なければ " または ' または >
で終わるかチェックして、そこの文字列を取ってくるという形かな?

100% どんなに正しくない HTML でもというのは無理だろうから、ある程度のとこ
ろで線引きはしておく必要はあるでしょうけど……IE がどこまで不正なのを解釈
しているかという資料はどこかにないかしらん。


-- matchRegex all String
rxScan :: String -> String -> [String]
rxScan pat str
     = case matchRegexAll (mkRegex pat) str of
         Just (before, "", "", _)         -> []
         Just (before, "", after, _)      -> rxScan pat (tail after)
         Just (before, matched, after, _) -> matched : rxScan pat after
         Nothing                          -> []

-- delete e from list
delete' e xs = filter (e/=) xs

trimHeadSpace :: String -> String
trimHeadSpace = dropWhile isSpace

deleteIndent :: String -> String
deleteIndent = unlines . map trimHeadSpace  . lines

data Datas = Link String | RDF String deriving (Show)
datas :: String -> Datas
datas str = if (take 2 str) == "<r" then RDF str else Link (delete '\r'  
$ delete' '\n' str)


dropString :: String -> String -> String
dropString = dropStringN 1

dropStringN :: Int -> String -> String -> String
dropStringN n dr str = drop n $ head $ filter (isPrefixOf dr) $ tails str

dropWithCloseBracket :: String -> String -> String
dropWithCloseBracket dr str = if notElem (head dr) str then dropString ">"  
str else dropString dr str

linkURIs :: Datas -> [String]
linkURIs strs =
   let
     parceTexts texts =
       case texts of
         Link str -> words str
         _ -> []
     uris string =
       if isPrefixOf "href" string || isPrefixOf "data" string ||  
isPrefixOf "src" string || isPrefixOf "linkhref" string
       || isPrefixOf "ahref" string || isPrefixOf "imgsrc" string ||  
isPrefixOf "objectdata" string
          then if elem '\"' string
            then Just (reverse $ dropWithCloseBracket "\"" $ reverse  
$ dropString "\"" string)
            else if elem '\'' string then Just (reverse  
$ dropWithCloseBracket "\'" $ reverse $ dropString "\'" string) else  
Nothing
          else Nothing
   in
     catMaybes $ map uris $ parceTexts strs

match = rxScan  
("(<link[^>]*>|<a[^>]*>|<img[^>]*>|<object[^>]*>|<rdf([[:print:]]|[[:space:]])*</rdf:RDF>)")  
$  deleteIndent html
matchDatas = map datas match
uris = concat $ map linkURIs matchDatas


-- 
shelarcy <shelarcy capella.freemail.ne.jp>
http://page.freett.com/shelarcy/