- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
开头;否-6ren">
事实上,我很确定我使用了错误的术语。这是我想要解决的问题:一个用于 markdown
格式的解析器,以及它的一个子集。
我的问题是 block 引用功能。 block 引用中的每一行都以 >
开头;否则一切都是 Markdown 文件中的正常结构。
你不能单独查看单独的行,因为你需要将段落与普通行分开,例如
> a
> b
不等于
> a
>
> b
以及类似的东西(如果列表被 block 引用,则相同,您不需要 x 列表,而是包含 x 元素的列表)。一种自然而简单的方法是“去掉” >
符号,自行解析 block 引用,忽略它周围的任何内容,用 BlockQuote
类型构造函数包装它,将在外部 AST 中并恢复原始输入的解析。如果我没记错的话,这就是 pango
所做的:
blockQuote :: MarkdownParser (F Blocks)
blockQuote = do
raw <- emailBlockQuote
-- parse the extracted block, which may contain various block elements:
contents <- parseFromString parseBlocks $ (intercalate "\n" raw) ++ "\n\n"
return $ B.blockQuote <$> contents
然后:
http://hackage.haskell.org/package/pandoc-1.5.1/docs/src/Text-Pandoc-Shared.html#parseFromString
-- | Parse contents of 'str' using 'parser' and return result.
parseFromString :: GenParser tok st a -> [tok] -> GenParser tok st a
parseFromString parser str = do
oldPos <- getPosition
oldInput <- getInput
setInput str
result <- parser
setInput oldInput
setPosition oldPos
return result
现在 parseFromString
对我来说看起来很老套,除此之外它也是 Parsec
而不是 attoparsec
所以我不能在我的项目中使用它。我不确定如何从 block 引用中获取该 Text
并解析它并返回解析结果,以便它“适合”当前解析。似乎不可能?
我一直在谷歌上搜索这个问题,我认为,pipes-parse
和conduit
可以在该领域提供帮助,尽管我很努力找到示例,我看到的内容看起来比“纯”parsec/attoparsec 解析器要差得多。
解析 block 引用的其他选项是重写通常的解析器,但使用 >
catch... 复杂化和重复很多。解析 block 引用,分别计算每一行并编写一些困惑的“合并”函数。或者解析到第一个 AST,它将在第一个 BlockquoteText
类型构造函数中包含作为 Text
的 block 引用,等待转换,其中它们将被单独解析,不是很优雅,但它有简单的好处,这确实很重要。
我可能会选择后者,但肯定有更好的方法吗?
最佳答案
我也问过自己同样的问题。为什么没有像您所描述的那样的嵌套解析器的标准组合器?我的默认模式是信任包作者,特别是当该作者还与他人共同编写了“Real World Haskell”时。如果缺少这样一个明显的功能,也许是设计使然,我应该寻找更好的方法。然而,我已经成功地说服自己,这样一个方便的组合器基本上是无害的。当全有或全无类型解析器适合内部解析时很有用。
import Data.Attoparsec.Text
import qualified Data.Text as T
import Data.Text(Text)
import Control.Applicative
我已将所需的功能划分为两个解析器。第一个,constP
,对某些给定文本执行“就地”解析。它将常量解析器的失败替换为 empty
(来自替代方案),但除此之外没有其他副作用。
constP :: Parser a -> Text -> Parser a
constP p t = case parseOnly p t of
Left _ -> empty
Right a -> return a
第二部分来自parseOf
,它根据外部解析的结果执行恒定的内部解析。 empty
这里的替代方案允许返回失败的解析而不消耗任何输入。
parseOf :: Parser Text -> Parser a -> Parser a
parseOf ptxt pa = bothParse <|> empty
where
bothParse = ptxt >>= constP pa
block 引用 Markdown 可以按照所需的方式编写。此实现需要完全解析生成的 block 。
blockQuoteMarkdown :: Parser [[Double]]
blockQuoteMarkdown = parseOf blockQuote ( markdownSurrogate <*
endOfInput
)
我只是实现了一个空格分隔 double 的快速解析器,而不是实际的 Markdown 解析器。解析器的复杂性来自于允许最后一个非空行,无论是否以新行结束。
markdownSurrogate :: Parser [[Double]]
markdownSurrogate = do
lns <- many (mdLine <* endOfLine)
option lns ((lns ++) . pure <$> mdLine1)
where
mdLine = sepBy double (satisfy (==' '))
mdLine1 = sepBy1 double (satisfy (==' '))
这两个解析器负责返回 block 引号内部的文本。
blockQuote :: Parser Text
blockQuote = T.unlines <$> many blockLine
blockLine :: Parser Text
blockLine = char '>' *> takeTill isEndOfLine <* endOfLine
最后,对解析器进行测试。
parseMain :: IO ()
parseMain = do
putStrLn ""
doParse "a" markdownSurrogate a
doParse "_" markdownSurrogate ""
doParse "b" markdownSurrogate b
doParse "ab" markdownSurrogate ab
doParse "a_b" markdownSurrogate a_b
doParse "badMarkdown x" markdownSurrogate x
doParse "badMarkdown axb" markdownSurrogate axb
putStrLn ""
doParse "BlockQuote ab" blockQuoteMarkdown $ toBlockQuote ab
doParse "BlockQuote a_b" blockQuoteMarkdown $ toBlockQuote a_b
doParse "BlockQuote axb" blockQuoteMarkdown $ toBlockQuote axb
where
a = "7 3 1"
b = "4 4 4"
x = "a b c"
ab = T.unlines [a,b]
a_b = T.unlines [a,"",b]
axb = T.unlines [a,x,b]
doParse desc p str = do
print $ T.concat ["Parsing ",desc,": \"",str,"\""]
let i = parse (p <* endOfInput ) str
print $ feed i ""
toBlockQuote = T.unlines
. map (T.cons '>')
. T.lines
*Main> parseMain
"Parsing a: \"7 3 1\""
Done "" [[7.0,3.0,1.0]]
"Parsing _: \"\""
Done "" []
"Parsing b: \"4 4 4\""
Done "" [[4.0,4.0,4.0]]
"Parsing ab: \"7 3 1\n4 4 4\n\""
Done "" [[7.0,3.0,1.0],[4.0,4.0,4.0]]
"Parsing a_b: \"7 3 1\n\n4 4 4\n\""
Done "" [[7.0,3.0,1.0],[],[4.0,4.0,4.0]]
"Parsing badMarkdown x: \"a b c\""
Fail "a b c" [] "endOfInput"
"Parsing badMarkdown axb: \"7 3 1\na b c\n4 4 4\n\""
Fail "a b c\n4 4 4\n" [] "endOfInput"
"Parsing BlockQuote ab: \">7 3 1\n>4 4 4\n\""
Done "" [[7.0,3.0,1.0],[4.0,4.0,4.0]]
"Parsing BlockQuote a_b: \">7 3 1\n>\n>4 4 4\n\""
Done "" [[7.0,3.0,1.0],[],[4.0,4.0,4.0]]
"Parsing BlockQuote axb: \">7 3 1\n>a b c\n>4 4 4\n\""
Fail ">7 3 1\n>a b c\n>4 4 4\n" [] "Failed reading: empty"
显着的差异在于失败的语义。例如,解析 axb
时并 block 引用 axb
,分别是下面两个字符串
7 3 1
a b c
4 4 4
和
> 7 3 1
> a b c
> 4 4 4
markdown 解析结果为
Fail "a b c\n4 4 4\n" [] "endOfInput"
而引用的结果是
Fail ">7 3 1\n>a b c\n>4 4 4\n" [] "Failed reading: empty"
Markdown 消耗了“7 3 1\n”,但是在引用的失败中没有报告这一点。相反,失败就变得要么全有,要么全无。
同样,在部分成功的情况下,不允许处理未解析的文本。但考虑到用例,我认为没有必要这样做。例如,如果解析类似于以下内容
"{ <tok> unhandled }more to parse"
哪里{}
表示已识别的 block 引用上下文,<tok>
在该内部上下文中进行解析。要想取得部分成功,就必须将“未处理”从 block 引用上下文中剔除,并以某种方式将其与“更多要解析的内容”结合起来。
我认为没有通用的方法可以做到这一点,但可以通过选择内部解析器返回类型来实现。例如,通过某些解析器 parseOf blockP innP :: Parser (<tok>,Maybe Text)
。但是,如果出现这种需要,我希望有比嵌套解析器更好的方法来处理这种情况。
也可能担心 attoparsec 部分解析的丢失。即执行constP
使用parseOnly
,这会折叠解析返回 Fail
和Partial
成单Left
故障状态。换句话说,我们失去了向内部解析器提供更多可用文本的能力。但是,请注意,要解析的文本本身就是外部解析的结果;只有在将足够的文本输入到外部解析后,它才可用。所以这也不应该是一个问题。
关于haskell - attoparsec: "nested"parsers -- 使用不同的解析器解析输入的子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31082272/
我一直在使用 AJAX 从我正在创建的网络服务中解析 JSON 数组时遇到问题。我的前端是一个简单的 ajax 和 jquery 组合,用于显示从我正在创建的网络服务返回的结果。 尽管知道我的数据库查
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我在尝试运行 Android 应用程序时遇到问题并收到以下错误 java.lang.NoClassDefFoundError: com.parse.Parse 当我尝试运行该应用时。 最佳答案 在这
有什么办法可以防止etree在解析HTML内容时解析HTML实体吗? html = etree.HTML('&') html.find('.//body').text 这给了我 '&' 但我想
我有一个有点疯狂的例子,但对于那些 JavaScript 函数作用域专家来说,它看起来是一个很好的练习: (function (global) { // our module number one
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 8 年前。 Improve th
我需要编写一个脚本来获取链接并解析链接页面的 HTML 以提取标题和其他一些数据,例如可能是简短的描述,就像您链接到 Facebook 上的内容一样。 当用户向站点添加链接时将调用它,因此在客户端启动
在 VS Code 中本地开发时,包解析为 C:/Users//AppData/Local/Microsoft/TypeScript/3.5/node_modules/@types//index而不是
我在将 json 从 php 解析为 javascript 时遇到问题 这是我的示例代码: //function MethodAjax = function (wsFile, param) {
我在将 json 从 php 解析为 javascript 时遇到问题 这是我的示例代码: //function MethodAjax = function (wsFile, param) {
我被赋予了将一种语言“翻译”成另一种语言的工作。对于使用正则表达式的简单逐行方法来说,源代码过于灵活(复杂)。我在哪里可以了解更多关于词法分析和解析器的信息? 最佳答案 如果你想对这个主题产生“情绪化
您好,我在解析此文本时遇到问题 { { { {[system1];1;1;0.612509325}; {[system2];1;
我正在为 adobe after effects 在 extendscript 中编写一些代码,最终变成了 javascript。 我有一个数组,我想只搜索单词“assemble”并返回整个 jc3_
我有这段代码: $(document).ready(function() { // }); 问题:FB_RequireFeatures block 外部的代码先于其内部的代码执行。因此 who
背景: netcore项目中有些服务是在通过中间件来通信的,比如orleans组件。它里面服务和客户端会指定网关和端口,我们只需要开放客户端给外界,服务端关闭端口。相当于去掉host,这样省掉了些
1.首先贴上我试验成功的代码 复制代码 代码如下: protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
什么是 XML? XML 指可扩展标记语言(eXtensible Markup Language),标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。 你可以通过本站学习 X
【PHP代码】 复制代码 代码如下: $stmt = mssql_init('P__Global_Test', $conn) or die("initialize sto
在SQL查询分析器执行以下代码就可以了。 复制代码代码如下: declare @t varchar(255),@c varchar(255) declare table_cursor curs
前言 最近练习了一些前端算法题,现在做个总结,以下题目都是个人写法,并不是标准答案,如有错误欢迎指出,有对某道题有新的想法的友友也可以在评论区发表想法,互相学习🤭 题目 题目一: 二维数组中的
我是一名优秀的程序员,十分优秀!