Haskell 解析一个没有空格的单词的第一次出现

Haskell 解析一个没有空格的单词的第一次出现,haskell,attoparsec,Haskell,Attoparsec,设置 我需要在某个.txt文件中找到前面没有空格的单词的第一个匹配项。以下是可能的情况: -- * should succed t1 = "hello\t999\nworld\t\900" t2 = "world\t\900\nhello\t999\n" t3 = "world world\t\900\nhello\t999\n" -- * should fail t4 = "world\t\900\nhello world\t999\n" t5 = "hello world\t999\nwo

设置

我需要在某个.txt文件中找到前面没有空格的单词的第一个匹配项。以下是可能的情况:

-- * should succed
t1 = "hello\t999\nworld\t\900"
t2 = "world\t\900\nhello\t999\n"
t3 = "world world\t\900\nhello\t999\n"

-- * should fail
t4 = "world\t\900\nhello world\t999\n"
t5 = "hello world\t999\nworld\t\900"
t6 = "world hello\t999\nworld\t\900"
现在t6成功了,尽管它应该失败,因为我的解析器将使用任何字符,直到它到达hello。这是我的解析器:

我的解决方案

import Control.Applicative

import Data.Attoparsec.Text.Lazy
import Data.Attoparsec.Combinator
import Data.Text hiding (foldr)
import qualified Data.Text.Lazy as L (Text, pack)



-- * should succed
t1 = L.pack "hello\t999\nworld\t\900"
t2 = L.pack "world\t\900\nhello\t999\n"

-- * should fail
t3 = L.pack "world\t\900\nhello world\t999\n"
t4 = L.pack "hello world\t999\nworld\t\900"
t5 = L.pack "world hello\t999\nworld\t\900"

p = occur "hello"    

---- * discard all text until word `w` occurs, and find its only field `n`
occur :: String -> Parser (String, Int)
occur w = do
    pUntil w
    string . pack $ w
    string "\t"
    n <- natural 
    string "\n"
    return (w, read n)


-- * Parse a natural number
natural :: Parser String
natural = many1' digit

-- * skip over all words in Text stream until the word we want
pUntil :: String -> Parser String 
pUntil = manyTill anyChar . lookAhead . string . pack 
导入控件。应用程序
导入Data.Attoparsec.Text.Lazy
导入Data.c.Combinator
导入数据。文本隐藏(foldr)
将限定的Data.Text.Lazy导入为L(文本,包)
--*应该成功
t1=L.pack“你好\t999\nworld\t\900”
t2=L.pack“世界\t\900\nhello\t999\n”
--*应该失败
t3=L.pack“世界\t\900\nhello世界\t999\n”
t4=L.pack“hello world\t999\nworld\t\900”
t5=L.pack“世界你好\t999\nworld\t\900”
p=出现“你好”
----*丢弃所有文本,直到出现单词“w”,并找到其唯一字段“n”`
发生::字符串->解析器(字符串,Int)
发生w=do
蓬蒂尔w
一串每包$w
字符串“\t”

n以下是需要考虑的方法:

{-# LANGUAGE OverloadedStrings #-}

import Control.Applicative

import Data.Attoparsec.Text.Lazy
import Data.Attoparsec.Combinator
import Data.Text hiding (foldr)
import qualified Data.Text.Lazy as L (Text, pack)
import Data.Monoid

natural = many1' digit

-- manyTill anyChar (try $ char c <* eof)

pair0 w = do
  string (w <> "\t")
  n <- natural
  string "\n"
  return n

pair1 w = do
  manyTill anyChar (try $ string ("\n" <> w <> "\t"))
  n <- natural
  string "\n"
  return n

pair w = pair0 w <|> pair1 w

t1 = "hello\t999\nworld\t\900"
t2 = "world\t\900\nhello\t999\n"
t3 = "world world\t\900\nhello\t999\n"

-- * should fail
t4 = "world\t\900\nhello world\t999\n"
t5 = "hello world\t999\nworld\t\900"
t6 = "world hello\t999\nworld\t\900"

test t = parseTest (pair "hello") (L.pack t)

main = do
  test t1; test t2; test t3
  test t4; test t5; test t6
{-#语言重载字符串}
导入控制
导入Data.Attoparsec.Text.Lazy
导入Data.c.Combinator
导入数据。文本隐藏(foldr)
将限定的Data.Text.Lazy导入为L(文本,包)
导入数据.幺半群
自然=许多1'位

--manyTill anyChar(试试$char c这里有一种方法可以考虑:

{-# LANGUAGE OverloadedStrings #-}

import Control.Applicative

import Data.Attoparsec.Text.Lazy
import Data.Attoparsec.Combinator
import Data.Text hiding (foldr)
import qualified Data.Text.Lazy as L (Text, pack)
import Data.Monoid

natural = many1' digit

-- manyTill anyChar (try $ char c <* eof)

pair0 w = do
  string (w <> "\t")
  n <- natural
  string "\n"
  return n

pair1 w = do
  manyTill anyChar (try $ string ("\n" <> w <> "\t"))
  n <- natural
  string "\n"
  return n

pair w = pair0 w <|> pair1 w

t1 = "hello\t999\nworld\t\900"
t2 = "world\t\900\nhello\t999\n"
t3 = "world world\t\900\nhello\t999\n"

-- * should fail
t4 = "world\t\900\nhello world\t999\n"
t5 = "hello world\t999\nworld\t\900"
t6 = "world hello\t999\nworld\t\900"

test t = parseTest (pair "hello") (L.pack t)

main = do
  test t1; test t2; test t3
  test t4; test t5; test t6
{-#语言重载字符串}
导入控制
导入Data.Attoparsec.Text.Lazy
导入Data.c.Combinator
导入数据。文本隐藏(foldr)
将限定的Data.Text.Lazy导入为L(文本,包)
导入数据.幺半群
自然=许多1'位
--manyTill anyChar(try$char c语法分析器不是“查找y序列中第一个出现的x”的正确工具。您应该将整个字符串解析为一个数据结构,该结构存储(键、值)对以及它们出现的位置。您当前的问题是
t6
包含两个键/值对(一个在整个字符串中,一个在后缀中)因此回溯解析器自然会同时找到这两个键。无条件地解析每个键可以解决这一问题。使用attoparsec,您只能获取作为字节索引的位置,但这应该足以满足您的目的。对于“查找y序列中x的第一个匹配项”而言,解析器不是合适的工具。您应该将整个字符串解析为一个数据结构,该结构存储(键、值)对以及它们发生的位置。您当前的问题是
t6
包含两个键/值对(一个在整个字符串中,一个在后缀中)因此,回溯解析器自然会同时找到这两个键。无条件地解析每个键可以解决这一问题。使用attoparsec,您只能获得作为字节索引的位置,但这应该足以满足您的需要。