我在寻找方法来解析一系列可能在定义上有点灵活的方法时,了解了re.Scanner。它看起来(不知道它的意图)就像它正是我想要的,但我遇到了问题。
我定义了我的扫描仪:
scanner = re.Scanner([
(r"([0-9]+(?:\ h|h))", lambda scanner,token:("HOURS", token)),
])
results, remainder = scanner.scan(line)
应该能够在提供的字符串中找到类似'1h'或'1 h'的内容。但是,这仅在小时位于字符串的开头时才有效。
传入:
1 h words words words
bla 2 h words words
只有第一个条目被解析为一小时。由于无法读取Scanner,我认为它能够在提供的字符串中的任何位置找到匹配项,但它看起来就像刚开始时一样。它似乎也忽略了许多标准正则表达式控件(如()用于捕获和(?:)用于非捕获。
我应该在其他地方寻找吗?使用一个看起来不像是正式版的Python的类是不是一个坏主意?
答案 0 :(得分:3)
Scanner.scan
确实从行的开头开始,并要求它的每一位都匹配某种模式。 scan
方法在没有任何模式匹配的第一个点停止,并且其余字符串将作为remainder
返回。
如果你想跳过任何不匹配的东西,只需输入
即可(r'.', lambda scanner, token: None),
在模式/函数列表的末尾。
Scanner
类已经在标准库中存在了几年(at least as far back as 2003),它只是没有记录(但是?)。
我认为你不必担心它会很快消失。
即使它消失了,Scanner
类的定义也很短,而且是right here。
import re
line = '''\
1 h words words words
bla 2 h words words
'''
scanner = re.Scanner([
(r"([0-9]+(?:\ h|h))", lambda scanner, token: ("HOURS", token)),
(r'.', lambda scanner, token: None),
], flags=re.DOTALL)
results, remainder = scanner.scan(line)
print(results)
产量
[('HOURS', '1 h'), ('HOURS', '2 h')]