Python 如何动态标识数据文件中的未知分隔符?

Python 如何动态标识数据文件中的未知分隔符?,python,parsing,csv,text-files,textinput,Python,Parsing,Csv,Text Files,Textinput,我有三个输入数据文件。每种方法对其中包含的数据使用不同的分隔符。数据文件1如下所示: apples | bananas | oranges | grapes quarter, dime, nickel, penny horse cow pig chicken goat 它将打印包含所有可接受字符计数的词典。在每种情况下,空格总是赢的,所以我不能依靠它来告诉我分隔符是什么。 但是我想不出更好的方法来做这件事 有什么建议吗?如果您使用的是python,我建议您使用所有有效的预期分隔符在线调用: &g

我有三个输入数据文件。每种方法对其中包含的数据使用不同的分隔符。数据文件1如下所示:

apples | bananas | oranges | grapes quarter, dime, nickel, penny horse cow pig chicken goat 它将打印包含所有可接受字符计数的词典。在每种情况下,空格总是赢的,所以我不能依靠它来告诉我分隔符是什么。

但是我想不出更好的方法来做这件事


有什么建议吗?

如果您使用的是python,我建议您使用所有有效的预期分隔符在线调用:

>>> l = "big long list of space separated words"
>>> re.split(r'[ ,|;"]+', l)
['big', 'long', 'list', 'of', 'space', 'separated', 'words']
唯一的问题是其中一个文件使用分隔符作为数据的一部分

如果必须识别分隔符,最好的办法是计算除空格以外的所有内容。如果几乎没有出现,则可能是空格,否则是映射字符的最大值


不幸的是,真的没有办法确定。可以用逗号填充空格分隔的数据,也可以用分号填充|分隔的数据。它可能并不总是有效。

试试Python CSV的标准怎么样:


由于空间的问题,我最终选择了正则表达式。这是我完成的代码,以防有人感兴趣,或者可以使用其中的任何其他内容。顺便说一句,找到一种动态识别列顺序的方法是很好的,但我意识到这有点棘手。与此同时,我正在用老把戏来解决这个问题

用于填充glob.glob(os.path.join(self.\u input\u dir,self.\u file\u mask)):
#想不出一个办法把它变成一个街区
#(而不是三个独立的if/elif。但是您可以看到拆分是
#如果有人能想出更好的方法,
#我洗耳恭听!!:)
对于打开的行(填充,'r')。readlines():
如果infle.find('逗号')>-1:
datefmt=“%m/%d/%Y”
最后,第一,性别,颜色,多勃劳=\
[x.strip()用于重新拆分中的x(r'[,|“\t]+',行)]
elif infle.find('space')>-1:
datefmt=“%m-%d-%Y”
最后一个、第一个、未使用、性别、多臂、颜色=\
[x.strip()用于重新拆分(r'[,|“\t]+',行)]中的x
elif infle.find('pipe')>-1: datefmt=“%m-%d-%Y” 最后,第一,未使用,性别,颜色,多臂=\ [x.strip()用于重新拆分中的x(r'[,|“\t]+',行)] #还有一种方法可以通过csv.Sniffer实现这一点,但是 #管道分隔符周围的空格也会混淆嗅探器,因此 #我不能用它。 否则:raise VALUERROR(INFLE+“不是可接受的输入文件。”)

这并不能真正解决问题。
在这种情况下,我得到的结果是,文件中的每个字符都被分割成自己的列表,比如:“['a']['p']['p']['l']['e']['s'][''.[''.''.['.'.'.]等等…”。相反,我想把每一行分成一个列表,“[‘苹果’、‘香蕉’、‘橘子’、‘葡萄’””,我想你是在尝试识别分隔符,这样你就可以分隔数据了。你为什么要识别分隔符?@Greg Gauthier:非常抱歉。我的意思是说重新分开。我已更改了答案以反映正确的方法。
infle='Data/pipe.txt'records=open(infle,'r')。读取()记录中的行:print line.split('|,;\t')
@Greg Gauthier,您可以尝试在正则表达式中添加+(请参见答案)。然后它将匹配连续的分隔符并删除大部分空列表项。ooh。那个很有趣!版本2.6中有吗?+1:一定要使用csv模块。解析带分隔符的文件,特别是当它们可能包含转义分隔符、带引号的字符串中的分隔符、带引号的字符串中的换行符等时,对于正则表达式来说并不是什么工作。一个正则表达式解决方案迟早会失败,错误会很微妙,很难找到。这是一个很好的答案——但对于OPs的第一个例子来说,它不起作用。输入的
苹果|香蕉|橙子|葡萄
声明分隔符为
'
。如果删除管道周围的空格,它将按预期工作。这是csv模块上的一个有趣功能,但如果您有
,请小心
作为分隔符(csv的另一个常用分隔符),并且任何其他值上都有逗号,嗅探器将返回
作为分隔符。示例
sniffer.sniff('quarter,cent;dime;nickel;penny')。分隔符将返回
,但如果您对分隔符的外观有所了解,可以设置具有优先级的分隔符:
sniffer.preferred=[';','|]
>>> l = "big long list of space separated words"
>>> re.split(r'[ ,|;"]+', l)
['big', 'long', 'list', 'of', 'space', 'separated', 'words']
import csv

sniffer = csv.Sniffer()
dialect = sniffer.sniff('quarter, dime, nickel, penny')
print dialect.delimiter
# returns ','
for infile in glob.glob(os.path.join(self._input_dir, self._file_mask)):
            #couldn't quite figure out a way to make this a single block 
            #(rather than three separate if/elifs. But you can see the split is
            #generalized already, so if anyone can come up with a better way,
            #I'm all ears!! :)
            for row in open(infile,'r').readlines():
                if infile.find('comma') > -1: 
                    datefmt = "%m/%d/%Y"
                    last, first, gender, color, dobraw = \
                            [x.strip() for x in re.split(r'[ ,|;"\t]+', row)]
                elif infile.find('space') > -1: 
                    datefmt = "%m-%d-%Y"
                    last, first, unused, gender, dobraw, color = \
                            [x.strip() for x in re.split(r'[ ,|;"\t]+', row)]
elif infile.find('pipe') > -1: datefmt = "%m-%d-%Y" last, first, unused, gender, color, dobraw = \ [x.strip() for x in re.split(r'[ ,|;"\t]+', row)] #There is also a way to do this with csv.Sniffer, but the #spaces around the pipe delimiter also confuse sniffer, so #I couldn't use it. else: raise ValueError(infile + "is not an acceptable input file.")