如何使用管道用单个标签替换双标签?

时间:2015-08-22 14:17:58

标签: haskell haskell-pipes

我需要用单个选项卡替换bytestring中的所有连续选项卡,如下所示:

"___\t___\t\t___\t\t\t___"

变为

"___\t___\t___\t___"

没有想法如何做。

经过半个小时的计算,我设法替换了第一次出现的双标签,就像这样(甚至这实际上是错误的 - 它会在空字符串中添加一个标签):

import qualified Pipes.ByteString as PB
import qualified Data.ByteString as B

removeConsecutiveTabs =
  PB.break (== tab) . mapped %~ \p -> do
    yield (B.singleton tab)
    PB.dropWhile (== tab) p

但是,我仍然不知道如何替换所有出现的连续标签。

2 个答案:

答案 0 :(得分:1)

密钥是在字节流上操作而不是字节串块之一。这可以通过来自pipes-bytestring(和pipes-text)的 var x = document.getElementsByTagName("div")[0].getAttribute("data-ls"); var x = x.split(":"); var val = x[1].split(';'); alert(val[0]); 来完成。这是一个不是特别复杂的演示:

pack
{-# LANGUAGE OverloadedStrings #-}

import Pipes
import qualified Pipes.ByteString as PB
import qualified Data.ByteString as B
import Control.Monad
import Control.Lens (over)

test byst = runEffect $
    removingConsecutiveTabs (PB.fromLazy byst) >-> PB.stdout

removingConsecutiveTabs :: Monad m
                        => Producer B.ByteString m r
                        -> Producer B.ByteString m r
removingConsecutiveTabs = over PB.pack tabGatekeeper

tabGatekeeper :: Monad m => Producer PB.Word8 m r -> Producer PB.Word8 m r
tabGatekeeper = go False
    where
    go wasTab stream = do
        ex <- lift $ next stream
        case ex of
            Left r -> return r
            Right (x, stream') -> do
                let thisIsATab = w8IsTab x
                unless (wasTab && thisIsATab) $ yield x
                go thisIsATab stream'

    w8IsTab x = toEnum (fromIntegral x) == '\t'

答案 1 :(得分:0)

这是一个不使用$("#me").stop(true).off('mouseenter mouseleave'); 但只使用基本管道操作的解决方案。其中一个问题是数据是块状的,你必须跟踪最后一个块是否以标签结束:

PB.break

如果我使用{-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE OverloadedStrings #-} module Lib5 where import Pipes import Pipes.ByteString import qualified Data.ByteString.Char8 as BS import Control.Monad printAll = forever $ do a <- await; lift $ putStrLn $ "got: " ++ show a endsWith bs ch = BS.length bs > 0 && BS.last bs == ch convertDoubleTabs = await >>= go0 -- no precediing tab go0 b = do let (pre,post) = BS.breakSubstring "\t\t" b yield pre if BS.length post == 0 then if endsWith pre '\t' then await >>= go1 else await >>= go0 else do yield "\t" go0 (BS.drop 2 post) -- last chunk ended in a tab go1 b = do if BS.length b == 0 then await >>= go1 else if BS.index b 0 == '\t' then go0 (BS.drop 1 b) else go0 b example1 = runEffect $ each [ "this", "is\t an", "\t\texample\t", "\t."] >-> convertDoubleTabs >-> printAll 和镜头找出解决方案,我会添加此答案。

转换所有连续标签:

Pipes.ByteString