Racket match函数匹配失败,如何正确提取指定字段后的数字?
问题分析与解决方案
失败原因
- 贪婪匹配导致范围溢出:第一种方法中,
cap ...采用贪婪匹配逻辑,会收集从captain:之后到first-officer:前的所有字符(包括others:30)。因为_ ...会尽可能跳过更多内容来满足后续模式,使得cap的匹配范围远超预期的数字部分。 - 固定长度匹配不灵活且逻辑错误:第二种方法用
cap ..2试图限制数字长度,但数字可能是1位、3位等多种长度,适用性差;同时模式中的空格匹配逻辑未锚定到captain:数字后的第一个空格,依然会出现匹配范围错误。
正确实现方式
方式一:使用正则表达式(推荐)
Racket的regexp-match*可以直接提取目标数字,代码简洁且灵活:
(define str "abc captain:10 others:30 first-officer:20 alt:40") (regexp-match* #rx"(captain|first-officer):(\\d+)" str #:match-select (lambda (m) (second m)))
执行结果:'("10" "20")
方式二:修正字符列表匹配模式
如果坚持使用match处理字符列表,需精确匹配连续数字字符,避免贪婪匹配溢出:
(define str "abc captain:10 others:30 first-officer:20 alt:40") (match (string->list str) [(list _ ... #\i #\n #\: (and cap (or #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9) ...) _ ... ; 跳过数字后的非目标内容 #\e #\r #\: (and fst (or #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9) ...) _ ...) (list (list->string cap) (list->string fst))])
执行结果:'("10" "20")
内容的提问来源于stack exchange,提问作者lyl
相关产品推荐
相关产品推荐

