我试图通过以下测试:
from pyparsing import Word, nums, StringStart, StringEnd
import pytest
def get_square_feet(string):
area = Word(nums+",")("area").setParseAction(lambda s, l, t: [int(t[0].replace(',', ''))])
expression = StringStart() + area + "sqft" + StringEnd()
return expression.parseString(string).get("area")
def test_get_square_feet():
assert get_square_feet("800 sqft") == 800
assert get_square_feet("9,000 sqft") == 9000
def test_get_square_feet_with_prefix():
assert get_square_feet("size: 12,000 sqft") is None
if __name__ == "__main__":
pytest.main([__file__])
然而,第二次测试失败,因为它导致ParseError
。相反,我想使用searchString
,但如果我在parseString
函数中将searchString
替换为get_square_feet
,我也会收到错误,因为函数返回{{1 }}。有人能指出我这里有什么问题吗?
答案 0 :(得分:2)
这是使用pyparsing的相应代码,捕获ParseException:
from pyparsing import Word, nums, StringStart, StringEnd, ParseException
def get_square_feet(string):
area = Word(nums+",")("area").setParseAction(lambda s, l, t: [int(t[0].replace(',', ''))])
expression = StringStart() + area + "sqft" + StringEnd()
try:
return expression.parseString(string).get("area")
except ParseException:
return None
答案 1 :(得分:1)
这是一个使用parsy的解决方案,它在许多方面类似于pyparsing,但具有更好的接口和实现IMO。
from parsy import regex
def get_square_feet(s):
area = regex(r'[0-9,]+').map(lambda s: int(s.replace(',', '')))
return (area << string(" sqft") | regex('.*').result(None)).parse(s)
在这里,我们使用|
组合器回退到接受任何内容的正则表达式,然后根据需要生成None
。您也可以通过捕获ParseError
异常并在这种情况下返回None
来实现它。
答案 2 :(得分:0)
以下是使用正则表达式传递测试的get_square_feet
的实现:
def get_square_feet(string):
match = re.match(r'^([\d,]+) sqft$', string)
return int(match.groups()[0].replace(',', '')) if match else None
原则上,PyParsing应该比正则表达式更容易使用,所以我仍然对使用PyParsing的解决方案感兴趣。