用专有名称解析以空格分隔的行

时间:2018-12-14 06:22:56

标签: python file csv text

我有一个用空格分隔的文本文件。

格式为:

姓氏名字值1值2

LastName可以是Van Horn或Roberts或Silly Last Name-很难知道有多少空格。

名字可以相同-带有空格的多个单词。

Value1是4个固定值之一,但还包含空格

Value2与Value1的格式相同

我认为,因为Value1具有固定的4个已知值,所以我至少应该能够获得“ LastName FirstName”,Value1,Value2

我想将此数据文件转换为cab文件。最好是LastName,FirstName,Value1,Value2

虽然我在逻辑上挣扎。

感谢任何人可以提供的帮助以帮助我前进。

我尝试过的代码(部分来自此站点):

input_file = open("file.txt", "r")
for line in input_file:
    (LastName, FirstName, Value1, Value2) = line.strip().split(" ")
    print(LastName, ",", FirstName, ",", Value1, ",", Value2, "\n")
input_file.close()

File.txt:

Van Horn Sir Steven Value1 v1 Value2 V2

预期输出:

Van Horn, Sir Steven, Value1 v1, Value2 V2

将接受:

Van Horn Sir Steve, Value V1, Value V2

错误:

Traceback (most recent call last):
  File "C:\Users\tokyomike\Desktop\parse.py", line 4, in <module>
    (LastName, FirstName, Value1, Value2) = line.strip().split(" ")
ValueError: too many values to unpack (expected 4)

2 个答案:

答案 0 :(得分:1)

split()函数删除所有空白并将每个空白作为一个单独的元素接受。因此,对于您的情况Van Horn Sir Steven Value1 v1 Value2 V2,您将有8个单独的值,但是您仅需 4个变量 LastName, FirstName, Value1, Value2即可将它们拆包。这就是引发ValueError: too many values to unpack (expected 4)错误的原因。 让我们测试一下:

x,a,s = [1,2,3,4]

输出:

C:\Users\Desktop>py x.py
Traceback (most recent call last):
  File "x.py", line 1, in <module>
    x,a,s = [1,2,3,4]
ValueError: too many values to unpack (expected 3)

完全一样的错误。

解决方案:

import re

string = 'Van Horn Sir Steven Value1 v1 Value2 V2'
str = re.findall(r'(\w+?\s\w+)', string)
str = ', '.join(str)
print(str)

输出:

C:\Users\Desktop>py x.py
Van Horn, Sir Steven, Value1 v1, Value2 V2

在您的情况下:

import re

input_file = open("file.txt", "r")
for line in input_file:
    str = re.findall(r'(\w+?\s\w+)', line)
    str = ', '.join(str)
    print(str)
input_file.close()

答案 1 :(得分:0)

因此-首先-关于您的例外情况:split()在每个上分割给定的字符串。 当然,这导致列表的长度比您尝试将其解压缩到的四个项目更长:

line = "Van Horn Sir Steven Value1 v1 Value2 V2"
print(line.split())  # ->['Van', 'Horn', 'Sir', 'Steven', 'Value1', 'v1', 'Value2', 'V2']

您可以使用星号解包来解决此问题:

line = "Van Horn Sir Steven Value1 v1 Value2 V2"

*name, key1, val1, key2, val2 = line.split()
print(f"name: {name}, {key1}: {val1}, {key2}: {val2}")

# Output-> name: ['Van', 'Horn', 'Sir', 'Steven'], Value1: v1, Value2: V2

这将为您提供name中的元素列表。

这时您可能会注意到: 通常,您的方法存在一个主要缺陷。 我们不知道姓氏在哪里开始/姓氏在哪里结束,因为它们可以有任意多个元素。 因此,基本上是不可能解决的。

除非:您的示例包括一个“先生”。 如果每个名字都有一个“先生”,“女士”,“先生”。或基本上任何固定的关键字,都可以生成这些关键字的列表,并将其中一个单词的首次出现时的列表分为名字和姓氏。