检查列表是否包含与

时间:2017-10-20 17:13:55

标签: c# regex string csv

我试图找出实现以下方案的最有效方法:

我有一个这样的清单:

public static IEnumerable<string> ValidTags = new List<string> {
  "ABC.XYZ",
  "PQR.SUB.UID",
  "PQR.ALI.OBD",
};

我有一个包含多列的巨大CSV。其中一列是tags。此列要么包含空值,要么包含上述值之一。问题是,标记列可能包含&#34; ABC.XYZ?@&#34;等值。即有效标签加上一些无关的字符。我需要使用有效标记更新此类列,因为它们&#34; 紧密匹配&#34;我们的有效标签之一。

示例:

  • 如果CSV包含PQR.ALI.OBD?,则使用有效标记PQR.ALI.OBD
  • 对其进行更新
  • 如果CSV包含PQR.ALI.OBA,则无效,只需添加后缀无效并更新PQR.ALI.OBA-invalid

我试图找出最好的方法来做到这一点。

我目前的做法是:

  1. 以CSV格式遍历每列,获取tagValue
  2. 现在检查我们的tagValue是否包含列表
  3. 中的任何字符串
  4. 如果它包含但不完全相同,请使用它包含的值更新它。
  5. 如果它不包含&#34;列表中的任何值,添加后缀无效。
  6. 有更好/更有效的方法吗?

    更新

    这个清单只有5个项目,我在这里展示了3个。 额外的字符只是在最后,而且这种情况正在发生,因为人们正在编辑excel web版本中的那些CSV并且会弄乱一些条目。

    我目前的代码:(我确定有更好的方法可以做到这一点,C#也是新的,所以请告诉我如何改进这一点)。我使用CSVHelper来获取CSV单元格。

    var record = csv.GetRecord<Record>();
    string tag = csv.GetField(10); //tag column number in CSV is 10
    /* Criteria for validation:
    * tag matches our list, but has extraneous chars - strip extraneous chars and update csv
    * tag doesn't match our list - add suffix invalid.*/
    int listIndex = 0;
    bool valid;
    foreach (var validTags in ValidTags) //ValidTags is the enum above
    {
        if (validTags.Contains(tag.ToUpper()) && !string.Equals(validTags, subjectIdentifier.ToUpper()))
        {
         valid = true;
         continue; //move on to next csv row.
        //this means that tag is valid but has some extra characters appended to it because of web excel, strip extra charts
    
        }
        listIndex++; 
        if(listIndex == 3 && !valid) { 
         //means we have reached the end of the list but not found valid tag 
         //add suffix invalid and move on to next csv row
        }
    }
    

1 个答案:

答案 0 :(得分:0)

由于您说额外的字符仅在最后,并且假设原始标记仍然存在于额外字符之前,您可以只搜索每个标记的列表以查看标记是否包含列表中的条目。如果是,则将其更新为正确的条目(如果它不是完全匹配),如果不是,则附加&#34; -invalid&#34;标记到它。

在执行此操作之前,我们可能需要先对列表Descending进行排序,以便在我们搜索时找到最接近(最长)的匹配(在列表中的一个项目以列表中的另一个项目开头的情况下) )。

var csvPath = @"f:\public\temp\temp.csv";
var entriesUpdated = 0;

// Order the list so we match on the most similar match (ABC.DEF before ABC)
var orderedTags = ValidTags.OrderByDescending(t => t);
var newFileLines = new List<string>();

// Read each line in the file
foreach (var csvLine in File.ReadLines(csvPath))
{
    // Get the columns
    var columns = csvLine.Split(',');

    // Process each column
    for (int index = 0; index < columns.Length; index++)
    {
        var column = columns[index];

        switch (index)
        {
            case 0: // tag column
                var correctTag = orderedTags.FirstOrDefault(tag =>
                    column.IndexOf(tag, StringComparison.OrdinalIgnoreCase) > -1);

                if (correctTag != null)
                {
                    // This item contains a correct tag, so 
                    // update it if it's not an exact match
                    if (column != correctTag)
                    {
                        columns[index] = correctTag;
                        entriesUpdated++;
                    }
                }
                else
                {
                    // This column does not contain a correct tag, so mark it as invalid
                    columns[index] += "-invalid";
                    entriesUpdated++;
                }

                break;

            // Other cases for other columns follow if needed
        }
    }

    newFileLines.Add(string.Join(",", columns));
}

// Write the new lines if any were changed
if (entriesUpdated > 0) File.WriteAllLines(csvPath, newFileLines);