Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-从数据行中提取并重新格式化字段名_Python_Regex_Text_Dictionary_Header - Fatal编程技术网

Python-从数据行中提取并重新格式化字段名

Python-从数据行中提取并重新格式化字段名,python,regex,text,dictionary,header,Python,Regex,Text,Dictionary,Header,我有一个平面文本文件(infle),我想重新构造。它有几个以制表符分隔的列,如下所示: Person1 HEIGHT=60;WEIGHT=100;AGE=22 Person2 HEIGHT=62;WEIGHT=101;AGE=25 Person3 HEIGHT=64;WEIGHT=110;AGE=29 PERSON HEIGHT WEIGHT AGE 1 60 100 22 2 62

我有一个平面文本文件(infle),我想重新构造。它有几个以制表符分隔的列,如下所示:

 Person1    HEIGHT=60;WEIGHT=100;AGE=22
 Person2    HEIGHT=62;WEIGHT=101;AGE=25
 Person3    HEIGHT=64;WEIGHT=110;AGE=29
 PERSON    HEIGHT    WEIGHT    AGE
 1         60        100       22
 2         62        101       25
 3         64        110       29
我希望它看起来像这样:

 Person1    HEIGHT=60;WEIGHT=100;AGE=22
 Person2    HEIGHT=62;WEIGHT=101;AGE=25
 Person3    HEIGHT=64;WEIGHT=110;AGE=29
 PERSON    HEIGHT    WEIGHT    AGE
 1         60        100       22
 2         62        101       25
 3         64        110       29
您可以看到,第二列实际上包含几个以分号分隔的标题/值字段,我想将它们重新构造为典型的列标题行

现在我有:

for line in infile:
        line = line.split("\t")
        line_meta = line[1].split(";")
        print line_meta
我认为最好的解决方案是现在循环行\元变量,使用正则表达式检测标题名称(检测以多个大写字母开头,以“=”\结尾的字符串),将每个标题作为键添加到字典中,然后将字符串的其余部分作为值存储。然后,对于下一行,如果检测到相同的头,只需将其附加到现有字典中

是否有人可以在此代码方面提供帮助或提供有关如何继续的反馈

多谢各位

编辑:感谢您的回复。在本例中,我简化了数据,但下面是一个实际的元列的外观(仍然是分隔的,但值类型是混合的):


您可以只使用一个正则表达式来拆分键=值对:

import re

key_value = re.compile('(?P<key>[A-Z]+)=(?P<value>\[^\s=;]+)(?:(?=;)|$)')
(?:…)
组是非捕获组;此处仅用于标记
|
或符号所适用的内容。模式匹配
=
符号前的大写字符,以及任何非空白的字符,如
=
字符,前提是有一个
或值后面的字符串结尾

这将为每行拆分键和值:

>>> key_value = re.compile('(?P<key>[A-Z]+)=(?P<value>[^\s=;]+)(?:(?=;)|$)')
>>> key_value.findall('Person1\tHEIGHT=60;WEIGHT=100;AGE=22')
[('HEIGHT', '60'), ('WEIGHT', '100'), ('AGE', '22')]
然后,您可以使用以下方法编写这些内容,例如:


您可以只使用一个正则表达式来拆分键=值对:

import re

key_value = re.compile('(?P<key>[A-Z]+)=(?P<value>\[^\s=;]+)(?:(?=;)|$)')
(?:…)
组是非捕获组;此处仅用于标记
|
或符号所适用的内容。模式匹配
=
符号前的大写字符,以及任何非空白的字符,如
=
字符,前提是有一个
或值后面的字符串结尾

这将为每行拆分键和值:

>>> key_value = re.compile('(?P<key>[A-Z]+)=(?P<value>[^\s=;]+)(?:(?=;)|$)')
>>> key_value.findall('Person1\tHEIGHT=60;WEIGHT=100;AGE=22')
[('HEIGHT', '60'), ('WEIGHT', '100'), ('AGE', '22')]
然后,您可以使用以下方法编写这些内容,例如:

你可以试试这个

data = open('testfile.dat').read().split('\n')

def newcmp(x,y): 
    rv = cmp(len(x[1]), len(y[1]))
    if rv: return rv
    else: return cmp(x[0], y[0]) # alphabetical 

persons = {}
attributes = {}
nAttrs = 0
for l in data:
    pname , pvals = line.split('\t')[:2]
    for atName, atVal in (x.split('=') for x in pvals.psplit(';'))
        try:
            persons[pName][attributes[atName]] = atVal
        except KeyError:
            attributes[aName] = nAttrs
            persons[pName][attributes[atName]] = atVal
            nAttr += 1

headers = ['NAME'] + range(nAttrs)
for x in attributes.keys(): headers[attributes[x]+1] = x
values = []
for pName, pVals in sorted(persons.items(), cmp=newcmp)
    if len(pVals) < nAttrs: pVals += [0 for x in xrange(nAttrs - len(pVals))]
    values.append('\t'.join(('%d'%x for x in pVals)))

outfh = open('outputfile.dat', 'w')
outfh.write('%s\n%s\n'%('\t'.join(headers), '\n'.join(values)))
outfh.close()
data=open('testfile.dat').read().split('\n')
def newcmp(x,y):
rv=cmp(len(x[1]),len(y[1]))
如果是rv:返回rv
else:按字母顺序返回cmp(x[0],y[0])
人={}
属性={}
nAttrs=0
对于l in数据:
pname,pvals=line.split('\t')[:2]
对于atName,对于pvals.psplit(“;”)中的x,在(x.split(“=”)中使用atVal
尝试:
人员[pName][attributes[atName]]=atVal
除KeyError外:
属性[aName]=nAttrs
人员[pName][attributes[atName]]=atVal
nAttr+=1
标题=['NAME']+范围(nAttrs)
对于attributes.keys()中的x:头[attributes[x]+1]=x
值=[]
对于pName,pVals已排序(persons.items(),cmp=newcmp)
如果len(pVals)
您可以试试这个

data = open('testfile.dat').read().split('\n')

def newcmp(x,y): 
    rv = cmp(len(x[1]), len(y[1]))
    if rv: return rv
    else: return cmp(x[0], y[0]) # alphabetical 

persons = {}
attributes = {}
nAttrs = 0
for l in data:
    pname , pvals = line.split('\t')[:2]
    for atName, atVal in (x.split('=') for x in pvals.psplit(';'))
        try:
            persons[pName][attributes[atName]] = atVal
        except KeyError:
            attributes[aName] = nAttrs
            persons[pName][attributes[atName]] = atVal
            nAttr += 1

headers = ['NAME'] + range(nAttrs)
for x in attributes.keys(): headers[attributes[x]+1] = x
values = []
for pName, pVals in sorted(persons.items(), cmp=newcmp)
    if len(pVals) < nAttrs: pVals += [0 for x in xrange(nAttrs - len(pVals))]
    values.append('\t'.join(('%d'%x for x in pVals)))

outfh = open('outputfile.dat', 'w')
outfh.write('%s\n%s\n'%('\t'.join(headers), '\n'.join(values)))
outfh.close()
data=open('testfile.dat').read().split('\n')
def newcmp(x,y):
rv=cmp(len(x[1]),len(y[1]))
如果是rv:返回rv
else:按字母顺序返回cmp(x[0],y[0])
人={}
属性={}
nAttrs=0
对于l in数据:
pname,pvals=line.split('\t')[:2]
对于atName,对于pvals.psplit(“;”)中的x,在(x.split(“=”)中使用atVal
尝试:
人员[pName][attributes[atName]]=atVal
除KeyError外:
属性[aName]=nAttrs
人员[pName][attributes[atName]]=atVal
nAttr+=1
标题=['NAME']+范围(nAttrs)
对于attributes.keys()中的x:头[attributes[x]+1]=x
值=[]
对于pName,pVals已排序(persons.items(),cmp=newcmp)
如果len(pVals)
感谢您的回复。您能建议如何编辑key_值以容纳不仅仅是数字的值吗?就我的理解水平而言,您的正则表达式非常复杂,但我尝试将其修改为
”(?P[A-Z]+)=(?P\S+(:(?=)|$)”
,但它没有确定字段properly@alexhli:您可以使用
\w+
作为单词字符,所以a-z加0-9。@alexhli:啊,我错过了您提供的实际示例。我已经更新了正则表达式,使其更加自由,并为您发布了一个演示。您的新演示效果非常好!最后一个问题(我希望),出于某种原因,它现在正在最后一个字段周围打印“”,知道为什么吗?所以它看起来像是
person160100“22”
它包含空格;我们可以在字符类中添加不允许的空白:
[^\s;=]+
。CSV文件在值周围使用引号表示
22
之后的额外空间仍然是值的一部分。感谢您的回复。您能建议如何编辑key_值以容纳不仅仅是数字的值吗?就我的理解水平而言,您的正则表达式非常复杂,但我尝试将其修改为
”(?P[A-Z]+)=(?P\S+(:(?=)|$)”
,但它没有确定字段properly@alexhli:您可以使用
\w+
作为单词字符,所以a-z加0-9。@alexhli:啊,我错过了您提供的实际示例。我已经更新了正则表达式,使其更加自由,并为您发布了一个演示。您的新演示效果非常好!最后一个问题(我希望),出于某种原因,它现在正在最后一个字段周围打印“”,知道为什么吗?所以它看起来像是
person160100“22”
它包含空格;我们可以在character类中添加不允许的空白: