コンジットを使用してテキストを分割するときに問題が発生します。Conduit with Windowsで分割する
私が扱っているソースデータは残念ながら、同じファイル内に\r\n
と\n
の両方のシーケンスを含む行末とは一貫していません。
私はいくつかの例では、末尾\r
を私に残した、Data.Conduit.Binary
でlines
機能を見つけたが、それシングルバイトで「分割」、(賢明に十分\n
、)しています。
現在の実装では、それがないように動作する、と私は私が一緒に解決策のいくつかの種類をハック可能性がほとんど確信していますが、これを行うには、私は考えることができる唯一の方法は、のようなものになるだろう、なぜ私が理解:
lines' = do
loop $ T.pack ""
where loop acc = do
char <- await
case char of
Nothing -> return()
Just x -> do
case (isOver $ acc `T.append` x) of
(True,y) -> yield y
(False,y) -> loop y
where isOver n
| (T.takeEnd 2 n == _rLn) = (True, T.dropEnd 2 n)
| (T.takeEnd 1 n == _Ln) = (True, T.dropEnd 1 n)
| otherwise = (False,n)
where _rLn = T.pack $! "\r\n"
_Ln = T.pack $! "\n"
...これは控えめで、クルージングで、ひどく遅く感じます。
私が実際にやる必要があるのは、最後に読み込まれた文字が\r
だったとしたら「覚えている」ので、最後の2文字をチェックするのは間違っていますが、それを行うには賢明な方法は考えられません。
この問題の解決策を知っている人はいますか?
これはすばらしい答えです。「slidingWindow」についてのヒントについては、ありがたいことです。これは、私がまだ知りませんでしたいくつかの他の問題を解決します。 しかし、明らかに 'Data.Conduit.Text'パッケージの' foldLines'関数は、このユースケースをかなりうまく扱うことが分かっています。つまり、「ホイールを再作成しないでください」と思います。それを「正しい」答えとするつもりです。 –
@IronGremlin Nice find!それを確かに行ってください - それはかなり速いはずです。 – Alec