如何在EOF停止Haskell Parsec解析器

你死定了

因此,我正在编写一个小型解析器,它将提取<td>具有特定类的所有标签内容,例如这个<td class="liste">some content</td> --> Right "some content"

我将解析大html文件,但是我并不真正在乎所有杂音,因此想法是消耗所有字符直到到达为止,而<td class="liste">不是消耗所有字符(内容)直到</td>返回内容字符串。

如果文件中的最后一个元素是我的td.liste标签,则效果很好,但是如果我后面有一些文本,或者如果eof我的解析器使用了它,unexpected end of input则在执行时抛出该文本parseMyTest test3

-编辑
请参阅的结尾test3以了解什么是边缘情况。

到目前为止,这是我的代码:

import Text.Parsec
import Text.Parsec.String

import Data.ByteString.Lazy (ByteString)
import Data.ByteString.Char8 (pack)

colOP :: Parser String
colOP = string "<td class=\"liste\">"

colCL :: Parser String
colCL = string "</td>"

col :: Parser String
col = do
  manyTill anyChar (try colOP)
  content <- manyTill anyChar $ try colCL
  return content

cols :: Parser [String]
cols = many col

test1 :: String
test1 = "<td class=\"liste\">Hello world!</td>"

test2 :: String
test2 = read $ show $ pack test1

test3 :: String
test3 = "\n\r<html>asdfasd\n\r<td class=\"liste\">Hello world 1!</td>\n<td class=\"liste\">Hello world 2!</td>\n\rasldjfasldjf<td class=\"liste\">Hello world 3!</td><td class=\"liste\">Hello world 4!</td>adsafasd"

parseMyTest :: String -> Either ParseError [String]
parseMyTest test = parse cols "test" test

btos :: ByteString -> String
btos = read . show
埃里克

我创建了一个组合器skipTill p end该组合器将p一直应用end匹配,然后返回返回的内容end

相反,manyTill p end应用p直到end匹配,然后返回p解析器匹配的内容。

import Text.Parsec
import Text.Parsec.String

skipTill :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m end
skipTill p end = scan
    where
      scan  = end  <|> do { p; scan }

td :: Parser String
td = do
  string "("
  manyTill anyChar (try (string ")"))

tds = do r <- many (try (skipTill anyChar (try td)))
         many anyChar -- discard stuff at end
         return r

test1 = parse tds "" "111(abc)222(def)333" -- Right ["abc", "def"]

test2 = parse tds "" "111"                 -- Right []

test3 = parse tds "" "111(abc"             -- Right []

test4 = parse tds "" "111(abc)222(de"      -- Right ["abc"]

更新

这似乎也起作用:

tds' = scan
  where scan = (eof >> return [])
               <|> do { r <- try td; rs <- scan; return (r:rs) }
               <|> do { anyChar; scan }

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Haskell解析器组合器

来自分类Dev

Haskell Parsec组合器“很多”应用于接受空字符串的解析器

来自分类Dev

我应该如何使解析器并发?

来自分类Dev

如何加载BeautifulSoup页面解析器?

来自分类Dev

如何为散置元素列表编写一个parsec解析器?

来自分类Dev

如何访问Impala解析器

来自分类Dev

解析器(Haskell)的更好应用实例

来自分类Dev

如何使用args解析器

来自分类Dev

如何使用Haskell解析器解析任意列表?

来自分类Dev

如何检查特定的子解析器?

来自分类Dev

如何合并迭代器解析器

来自分类Dev

Parsec:如何使有关空格的解析器错误静音

来自分类Dev

如何使argparse解析器也充当子解析器

来自分类Dev

如何从<a> python解析器获取链接

来自分类Dev

Haskell的级联解析器

来自分类Dev

在Haskell中合并解析器

来自分类Dev

用解析器组合器解析Haskell本身

来自分类Dev

如何合并许多解析器?

来自分类Dev

使用Parsec的Haskell HTML解析器

来自分类Dev

在Haskell(Parsec)中链接两个解析器

来自分类Dev

Haskell Parsec组合器“很多”应用于接受空字符串的解析器

来自分类Dev

如何使用android的Json解析器?

来自分类Dev

如何访问Impala解析器

来自分类Dev

文件解析器-如何读取行

来自分类Dev

如何使用args解析器

来自分类Dev

如何添加JSON解析器库?

来自分类Dev

如何从<a> python解析器获取链接

来自分类Dev

这个C ++解析器如何工作?

来自分类Dev

如何测试这个 GEDCOM 解析器?