この質問は、先にStack Overflowで質問されたRemove html character entities in a stringの質問に似ています。 しかし、受け入れられた答えは、名前付きHTMLエンティティの問題には対処していません。文字ä
の場合はä
、したがって、すべてのHTMLをエスケープすることはできません。HTMLエンティティ(名前付きオブジェクトを含む)のアンエスケープ
非ASCII文字に名前付きHTMLエンティティを使用する従来のHTMLがあります。つまり、ö
の代わりにö
、ä
の代わりにä
などとなります。 A full list of all named HTML entitiesはWikipediaで入手できます。
私は、これらのHTMLエンティティを同等のキャラクタに迅速かつ効率的にエスケープしたいと考えています。
私は正規表現を使用して、Pythonの3でこれを行うには、コードを持っている:
import re
import html.entities
s = re.sub(r'&(\w+?);', lambda m: chr(html.entities.name2codepoint[m.group(1)]), s)
正規表現は、しかし、非常に、人気のある高速またはHaskellで使いやすいようではありません。
Text.HTML.TagSoup.Entity
(tagsoup)はコードポイントTPOマッピングという名前のエンティティのための便利なテーブルと機能を備えています。この、および正規表現-TDFAパッケージを使用して、私はHaskellでは同等極端に遅いを作り上げてきました:
{-# LANGUAGE OverloadedStrings #-}
import Data.ByteString.Lazy.Char8 as L
import Data.ByteString.Lazy.UTF8 as UTF8
import Text.HTML.TagSoup.Entity (lookupEntity)
import Text.Regex.TDFA ((=~~))
unescapeEntites :: L.ByteString -> L.ByteString
unescapeEntites = regexReplaceBy "&#?[[:alnum:]]+;" $ lookupMatch
where
lookupMatch m =
case lookupEntity (L.unpack . L.tail . L.init $ m) of
Nothing -> m
Just x -> UTF8.fromString [x]
-- regex replace taken from http://mutelight.org/articles/generating-a-permalink-slug-in-haskell
regexReplaceBy :: L.ByteString -> (L.ByteString -> L.ByteString) -> L.ByteString -> L.ByteString
regexReplaceBy regex f text = go text []
where
go str res =
if L.null str
then L.concat . reverse $ res
else
case (str =~~ regex) :: Maybe (L.ByteString, L.ByteString, L.ByteString) of
Nothing -> L.concat . reverse $ (str : res)
Just (bef, match , aft) -> go aft (f match : bef : res)
unescapeEntities
機能は、上記のPythonのバージョンよりも遅く数桁を実行します。 Pythonコードは7秒で約130 MBを変換できますが、私のHaskellバージョンは数分間実行されます。
私はスピードの点で、より良い解決策を探しています。しかし、可能であれば正規表現を避けたいと思います(とにかく正規表現を避けることは、ハスケルと手を携えているようです)。
あなたの実際の質問はここにはっきりしていません。より良いソリューションをお探しですか?現在のものを改善してもらいたいですか? –
ご質問が不明な場合は申し訳ありません。はい、私はより良い解決策を望んでいます。私は1です。遅すぎる2.正規表現を使用していますが、それは非常にハスケル慣習的ではありません。私の解決策は、主に「これまでに得たことです」という出発点として与えられました。私は根本的なアイデアにはオープンです。 – vicvicvic
どうやってファイルを読んでいるのですか?私が 'main = Data.ByteString.interact unescapeEntites'を作成し、' time cat big.txt | ./regex >>/dev/null'私は143Mが大きいために30秒を得る。txt(これはTagSoupにリストされているすべてのエンティティで、多くの 'a'が散在しています)。この間接的なことから、まだまだ不器用ですが、分はありません。 – applicative