我正在编写一个 python 程序来解析 txt 文件中的一些用户数据。 文本文件中的其中一行将包含用户的高度。 我已经指定了一个用户应该遵循的命令,例如
文件的第一行应该包含姓名,下一行,出生日期, 第三行,高度等
我也给了用户一个示例文件,看起来像这样
名字:名字姓氏
出生日期:16.04.2000
年龄:16岁
高度:5英尺9英寸
当我阅读文件时,我查看了每一行并使用“:”作为分隔符将其拆分。
第一个字段是我的列名称,如姓名、出生日期、年龄、高度。
在某些情况下,用户会忘记 Name 或 DOB 后的“:”,或者他们只会发送如下数据:
- 高度 5 英尺 9 英寸
- 5 英尺 9 英寸
- 5 英尺 9 英寸
- 5英尺9英寸
我决定使用的逻辑是:
- 在每行中查找“:”;如果找到了,那么我就有了我的领域。
- 否则,尝试找出它可能是什么数据。
高度的逻辑是这样的:
if any(heightword in file_line.upper() for heightword in ['FT', 'HEIGHT', 'FEET', 'INCH', 'CM'])
此 if
条件将查找与高度相关的词。
一旦我确定文件中的行包含高度,我希望能够在将该信息写入数据库之前将该信息转换为英寸。
请谁能帮我弄清楚如何将以下数据转换为英寸。
- 高度 5 英尺 9 英寸
- 5 英尺 9 英寸
- 5 英尺 9 英寸
- 5英尺9英寸
我知道,因为我正在尝试迎合各种用户输入。此列表并不详尽;我试图用这些作为例子来理解,然后当我发现新模式时我会继续添加代码。
最佳答案
pyparsing 是一个很好的模块,适用于像这样的简单解析情况,尤其是在尝试处理难以预测但结构合理的人工输入时。您可以使用一些友好命名的类(Keyword
、Optional
、OneOrMore
等)和算术运算符( '+'
用于序列,'|'
用于替代等),将较小的解析器组装成较大的解析器。这是一个为您的示例从位构建的解析器(也支持 ' 和 ' 用于英尺和英寸,以及分数英尺和英寸值)。(此示例使用最新版本的 pyparsing,版本 2.1.4):
samples = """\
Height 5 feet 9 inch
5 feet 9 inch
5ft 9 in
5feet 9inches
5'-9-1/2"
5' 9-1/2"
5' 9 1/2"
6'
3/4"
3ft-6-1/4 in
"""
from pyparsing import CaselessKeyword, pyparsing_common, Optional
CK = CaselessKeyword
feet_units = CK("feet") | CK("ft") | "'"
inch_units = CK("inches") | CK("inch") | CK("in") | '"'
# pyparsing_common.number will parse an integer or real, and convert to float
integer = pyparsing_common.number
fraction = integer + '/' + integer
fraction.addParseAction(lambda t: t[0]/t[-1])
qty = fraction | (integer + Optional(fraction)).addParseAction(lambda t:sum(t))
# define whole Height feet-inches expression
HEIGHT = CK("height") | CK("ht")
inch_qty = qty("inches")
feet_qty = qty("feet")
height_parser = Optional(HEIGHT) + (inch_qty + inch_units |
feet_qty + feet_units + Optional(inch_qty + inch_units))
# use parse-time callback to convert feet-and-inches to inches
height_parser.addParseAction(lambda t: t.get("feet", 0.0)*12 + t.get("inches", 0.0))
height_parser.ignore("-")
height_parser.runTests(samples)
# how to use the parser in normal code
height_value = height_parser.parseString(samples.splitlines()[0])[0]
print(height_value, type(height_value))
打印:
Height 5 feet 9 inch
[69.0]
5 feet 9 inch
[69.0]
5ft 9 in
[69.0]
5feet 9inches
[69.0]
5'-9-1/2"
[69.5]
5' 9-1/2"
[69.5]
5' 9 1/2"
[69.5]
6'
[72.0]
3/4"
[0.75]
3ft-6-1/4 in
[42.25]
69.0 <type 'float'>
关于python - re.sub python 收集高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37706783/