首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检测文本文件中使用的分隔符?

如何检测文本文件中使用的分隔符?
EN

Stack Overflow用户
提问于 2009-04-17 19:52:08
回答 13查看 38.3K关注 0票数 24

我需要能够同时解析CSV和TSV文件。我不能依靠用户来知道差异,所以我想避免让用户选择类型。是否有一种简单的方法来检测使用的是哪个分隔符?

一种方法是在每一行中阅读,同时计数制表符和逗号,找出每行中最一致的用法。当然,数据可以包括逗号或制表符,所以说起来容易做起来难。

编辑:这个项目的另一个有趣的方面是,我在读取文件时也需要检测它的模式,因为它可能是许多文件中的一个。这意味着在我能够解析它之前,我将不知道我有多少字段。

EN

回答 13

Stack Overflow用户

回答已采纳

发布于 2009-04-17 19:56:36

您可以在预览窗口中显示结果-类似于Excel所做的方式。很明显,在这种情况下使用的分隔符是错误的。然后,您可以允许它们选择一个分隔符范围,并实时进行预览更新。

然后,您只需简单地猜测开始使用的分隔符(例如,逗号或制表符是否放在第一位)。

票数 14
EN

Stack Overflow用户

发布于 2009-04-17 21:40:48

在Python中,csv模块中有一个嗅探器类,可以用来猜测给定文件的分隔符和引号。它的策略(引用于csv.py的docstring):

首先,查找两个相同的引号(可能的商标符)之间的文本,该引号前面和后面跟着相同的字符(可能的分隔符)。例如:

代码语言:javascript
复制
         ,'some text',

引号以最多者获胜,与分隔符相同。如果没有商标符,则不能以这种方式确定分隔符。

在这种情况下,请尝试以下方法:

分隔符应该在每一行上出现相同的次数。然而,由于格式错误的数据,它可能不会。我们不想要一个全部或不需要的方法,所以我们允许这个数字的小变化。

  1. 在每一行上构建每个字符的频率表。
  2. 构建了这个频率的频率表(元频率?),例如'x在10行中发生5次,在1000行中发生6次,在2行中发生7次‘
  3. 使用换频模式来确定该字符
  4. 的预期频率,找出字符实际满足该目标的频率(

H 110),最符合的字符是分隔符<>h 211>G 212。

由于性能原因,数据是以块计算的,因此它可以尝试评估数据中的最小部分,并在必要时评估附加块。

我不会在这里引用源代码-它在每个Python安装的Lib目录中。

请记住,CSV也可以使用分号代替逗号作为分隔符(例如,在德语版本的Excel中,CSV是分号分隔符,因为逗号在德国用作十进制分隔符.)

票数 18
EN

Stack Overflow用户

发布于 2015-02-03 23:55:05

我遇到了一个类似的需要,我想我会分享我的想法。我还没有通过它运行大量的数据,所以有可能的边缘情况。此外,请记住,此函数的目标不是100%确定分隔符,而是向用户提供最佳猜测。

代码语言:javascript
复制
/// <summary>
/// Analyze the given lines of text and try to determine the correct delimiter used. If multiple
/// candidate delimiters are found, the highest frequency delimiter will be returned.
/// </summary>
/// <example>
/// string discoveredDelimiter = DetectDelimiter(dataLines, new char[] { '\t', '|', ',', ':', ';' });
/// </example>
/// <param name="lines">Lines to inspect</param>
/// <param name="delimiters">Delimiters to search for</param>
/// <returns>The most probable delimiter by usage, or null if none found.</returns>
public string DetectDelimiter(IEnumerable<string> lines, IEnumerable<char> delimiters) {
  Dictionary<char, int> delimFrequency = new Dictionary<char, int>();

  // Setup our frequency tracker for given delimiters
  delimiters.ToList().ForEach(curDelim => 
    delimFrequency.Add(curDelim, 0)
  );

  // Get a total sum of all occurrences of each delimiter in the given lines
  delimFrequency.ToList().ForEach(curDelim => 
    delimFrequency[curDelim.Key] = lines.Sum(line => line.Count(p => p == curDelim.Key))
  );

  // Find delimiters that have a frequency evenly divisible by the number of lines
  // (correct & consistent usage) and order them by largest frequency
  var possibleDelimiters = delimFrequency
                    .Where(f => f.Value > 0 && f.Value % lines.Count() == 0)
                    .OrderByDescending(f => f.Value)
                    .ToList();

  // If more than one possible delimiter found, return the most used one
  if (possibleDelimiters.Any()) {
    return possibleDelimiters.First().Key.ToString();
  }
  else {
    return null;
  }   

}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/761932

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档