gpt4 book ai didi

haskell - Attoparsec:跳过括号中的术语?

转载 作者:行者123 更新时间:2023-12-02 02:11:13 25 4
gpt4 key购买 nike

我正在尝试在第 5 列中使用 JSON 制作适合导入到 mongoDB 的大型 TSV 文件。特别是我想将顶级和仅顶级关键字段更改为 _id。这是我目前所拥有的,它似乎有效但速度很慢:

{-# LANGUAGE OverloadedStrings #-}

import System.Environment (getArgs)
import Data.Conduit.Binary (sourceFile, sinkFile)
import Data.Conduit
import qualified Data.Conduit.Text as CT
import qualified Data.Conduit.List as CL
import qualified Data.Text as T
import Data.Monoid ((<>))
import Data.Attoparsec.Text as APT
import Control.Applicative

main = do
(inputFile : outputFile : _) <- getArgs
runResourceT $ sourceFile inputFile
$= CT.decode CT.utf8 $= CT.lines $= CL.map jsonify
$= CT.encode CT.utf8 $$ sinkFile outputFile

jsonify :: T.Text -> T.Text
jsonify = go . T.splitOn "\t"
where
go (_ : _ : _ : _ : content : _) = case parseOnly keyTo_id content of
Right res -> res <> "\n"
_ -> ""
go _ = ""

keyTo_id :: Parser T.Text
keyTo_id = skipWhile(/='{') >> T.snoc <$>
(T.cons <$> (char '{')
<*> (T.concat <$> many1 ( bracket
<|> (string "\"key\":" >> return "\"_id\":")
<|> APT.takeWhile1(\x -> x /= '{' && x /= '}' && x/= '"')
<|> T.singleton <$> satisfy (/= '}')
)))
<*> char '}'

bracket :: Parser T.Text
bracket = T.cons <$> char '{'
<*> scan 1 test
where
test :: Int -> Char -> Maybe Int
test 0 _ = Nothing
test i '}'= Just (i-1)
test i '{' = Just (i+1)
test i _ = Just i

根据分析器,58.7% 的时间花在括号中,19.6% 花在 keyTo_id 上,17.1% 花在 main 上。

如果括号匹配,肯定有更好的方法返回括号内的术语不变?

我简要地查看了 attoparsec-conduit,但我不知道如何使用该库,甚至不知道它是否可以用于这种用途。

编辑:更新了代码。数据来自openlibrary.org,e。 G。 http://openlibrary.org/data/ol_dump_authors_latest.txt.gz

最佳答案

使用扫描功能。它允许您扫描一个保持状态的字符串。在您的情况下,状态将是一个数字 — 到目前为止您遇到的左括号和右括号的区别。当您的状态为 0 时,这意味着大括号在当前子字符串内匹配。

诀窍在于您不会以这种方式解构和重建字符串,因此它应该更快。

此外,即使使用您当前的算法,您也可以通过使用惰性文本获得一些性能 — concat 函数会更有效地工作。

关于haskell - Attoparsec:跳过括号中的术语?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12712382/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com