parsing - 如何在解析中还读取多少个字符?
问题描述
我Numeric.readDec
用来解析数字和reads
解析字符串。但我还需要知道读取了多少个字符。
例如readDec "52 rest"
返回[(52," rest")]
, 并读取 2 个字符。但是我找不到一个很好的方法来知道它读取了 2 个字符。
您可以检查 的字符串长度show 52
,但如果输入为 052 则会给您错误的答案(此解决方案也不适用于具有转义字符的字符串解析)。您还可以使用从输入字符串的长度中减去后解析字符串的长度。但这对于具有许多解析的长字符串非常低效。
如何正确有效地完成这项工作(最好不要只编写自己的解析)?
解决方案
使用 just base
,而不是readDec
,您可以使用readDecP
from Text.Read.Lex
,它使用ReadP
解析器:
readDecP :: (Eq a, Num a) => ReadP a
中的gather
组合Text.ParserCombinators.ReadP
器返回解析结果以及解析的实际字符:
gather :: ReadP a -> ReadP (String, a)
您可以使用 运行解析器readP_to_S
,它会返回一个ReadS
解析器,该解析器是一个接受字符串并使用字符串的其余部分生成可能解析列表的函数。
readP_to_S :: ReadP a -> ReadS a
type ReadS a = String -> [(a, String)]
GHCi 中的一个例子:
> import Text.ParserCombinators.ReadP (gather, readP_to_S)
> import Text.Read.Lex (readDecP)
> readP_to_S (gather readDecP) "52 rest"
[(("52",52)," rest")]
> readP_to_S (gather readDecP) "0644 permissions"
[(("0644",644)," permissions")]
如果您希望结果明确,您可以简单地检查是否只有一个有效的解析,然后取第一个组件的长度来查找Char
解析的代码点数。
然而,这些解析器相当有限。如果您想要更容易使用、更快或能够产生更详细的错误消息的东西,那么您应该查看功能更全的解析包,例如regex-applicative
(regular grammars) 或megaparsec
(context-sensitive grammars)。
推荐阅读
- unity3d - Unity:外部应用的句柄窗口
- c# - 请求实体太大:如何在 Teams 上使用 Microsoft Bot Framework 修复此错误
- amazon-web-services - 了解 AWS VPC 和子网
- python - 无法访问嵌套字典的属性
- algorithm - 获取给定数字的所有可能组合以达到给定总和
- tizen - 使用模拟器测试配套应用程序?
- javascript - jQuery 为网格项分配一个类
- elasticsearch - too_long_frame_exception:查询 Elasticsearch 时 http header 大于 8192 字节
- reactjs - 带有 react-hook-form 和 react-input-mask 的 Matrial UI 不起作用
- java - 如何确定安装的 Java 是否支持模块?