2016-06-08 29 views
3

我正在写一个python程序来解析txt文件中的一些用户数据。 文本文件中的一行将包含用户的高度。 我已经指定了一个为了用户有望跟随像re.sub python收集高度

文件应包含名称,下一行,出生日期, 3号线,高度等

的第一行我也赐给一个示例文件看起来像这样

名用户:姓名
出生日期:2000年4月16日
年龄:16
身高:5英尺9英寸

当我读取文件时,我看着每一行,并使用':'作为分隔符来分割它。

第一个字段是我的专栏名称,例如name,dob,age,height。

在某些情况下,用户忘记了 ':' 姓名或出生日期之后,或者他们会简单地发送数据,如:

  • 身高:5英尺9英寸
  • 5英尺9寸
  • 5英尺9在
  • 5英尺9英寸

我已经决定要使用的逻辑是:

  1. 在每一行上寻找':';如果找到了,那么我有我的领域。
  2. 否则,请尝试找出可能的数据。

为高度的逻辑是这样的:

if any(heightword in file_line.upper() for heightword in ['FT', 'HEIGHT', 'FEET', 'INCH', 'CM']) 

if条件将查找具有高度相关联的话。

一旦我确定文件中的行包含高度,我希望能够在将信息写入数据库之前将该信息转换为英寸。

请有人帮助我解决如何将以下数据转换为英寸。

  • 身高:5英尺9英寸
  • 5英尺9寸
  • 5英尺9
  • 5英尺9英寸

我知道,因为我想,以满足各种用户输入。这份清单并非详尽无遗;我试图用这些作为例子来理解,然后我会继续添加代码,如果当我发现新的模式。

+0

你可以捕捉数字** [像](https://regex101.com/r/aD9nV5/1)** – rock321987

回答

1

在JavaScript中,有被称为“计算访问”的操作,进行如object[key],其中object属性读取时通过给定表达式的结果确定的,作为一种替代的正常的.运算符。我个人主要用它来迭代和读连字符和东西的属性,b它也可以用来从输入字符串中获得相关的想要的结果。
因此,在谷歌搜索整个下午并找出Python语法等之后,我可以编写一个简短的程序来完成此操作。

import re 
import string 
h = 0 
r = re.compile(r'(\d+)\s*(\w+)\b') 
def incr(m): 
    h+=m.group(1)*({'in':1,'inches':1,'inch':1,'foot':12,'feet':12,'cm':0.3937,'centimeter':0.3937,'centimeters':0.3937}[string.lower(m.group(2))]||1) # etc. etc. 
    return '' 
re.sub(r, incr, input) 
print h 

您可能希望限制可用于保持dict从得到太大的关键字。

+0

谢谢你。我在另一个程序中使用了一个类似的字典进行转换,但是我只是在用户输入数字,所以它更简单。今天会试试这个 –

5

pyparsing是一个很好的模块,用于解析这种简单的情况,尤其是在尝试处理比预测结果更差但仍然相当结构化的人工输入时。您可以使用一些友好命名的类(KeywordOptionalOneOrMore等)和算术运算符(序列为'+',替代品为'|'等)将分析器组合为较大的解析器。这里是一个解析器,由你的示例中的位构建而成(同样支持“和”,对于英尺和英寸以及分数英尺和英寸值也是如此)(本示例使用最新版本的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'>