秒差距 start-of-row 模式?
Parsec start-of-row pattern?
我正在尝试使用 Parsec 解析 mediawiki 文本。 mediawiki 标记中的某些结构只能出现在行的开头(例如 header 标记 ==header level 2==
)。在正则表达式中,我会使用锚点(例如 ^
)来查找一行的开头。
GHCi 的一次尝试是
Prelude Text.Parsec> parse (char '\n' *> string "==" *> many1 letter <* string "==") "" "\n==hej=="
Right "hej"
但这不太好,因为它会在文件的第一行失败。我觉得这应该是一个解决的问题...
Parsec 中最惯用的 "Start of line" 解析是什么?
也许您可以使用 many (char '\n')
而不仅仅是 char '\n'
。在解析器组合器中,没有 行首 的意义,因为它们总是 运行 在输入的开头。您唯一可以做的就是手动检查您的输入可以从哪些符号开始。使用 many (char '\n')
确保在 header == my header ==
.
之前只有零个或多个空行
您可以使用 getPosition
and sourceColumn
来找出解析器当前正在查看的列号。如果当前位置在一行的开头(例如在输入的开头或在 \n
或 \r
字符之后),列号将为 1
。
没有 built-in 组合器,但您可以轻松实现:
import Text.Parsec
import Control.Monad (guard)
startOfLine :: Monad m => ParsecT s u m ()
startOfLine = do
pos <- getPosition
guard (sourceColumn pos == 1)
现在您可以将 header 解析器编写为:
header = startOfLine *> string "==" *> many1 letter <* string "=="
我正在尝试使用 Parsec 解析 mediawiki 文本。 mediawiki 标记中的某些结构只能出现在行的开头(例如 header 标记 ==header level 2==
)。在正则表达式中,我会使用锚点(例如 ^
)来查找一行的开头。
GHCi 的一次尝试是
Prelude Text.Parsec> parse (char '\n' *> string "==" *> many1 letter <* string "==") "" "\n==hej=="
Right "hej"
但这不太好,因为它会在文件的第一行失败。我觉得这应该是一个解决的问题...
Parsec 中最惯用的 "Start of line" 解析是什么?
也许您可以使用 many (char '\n')
而不仅仅是 char '\n'
。在解析器组合器中,没有 行首 的意义,因为它们总是 运行 在输入的开头。您唯一可以做的就是手动检查您的输入可以从哪些符号开始。使用 many (char '\n')
确保在 header == my header ==
.
您可以使用 getPosition
and sourceColumn
来找出解析器当前正在查看的列号。如果当前位置在一行的开头(例如在输入的开头或在 \n
或 \r
字符之后),列号将为 1
。
没有 built-in 组合器,但您可以轻松实现:
import Text.Parsec
import Control.Monad (guard)
startOfLine :: Monad m => ParsecT s u m ()
startOfLine = do
pos <- getPosition
guard (sourceColumn pos == 1)
现在您可以将 header 解析器编写为:
header = startOfLine *> string "==" *> many1 letter <* string "=="