【问题标题】:find duplicate columns and replace matches with count查找重复列并用计数替换匹配项
【发布时间】:2013-08-26 23:58:04
【问题描述】:

我有一个制表符分隔的文件,其中有重复的命名标题;

[Column1] \t [Column2] \t [test] \t [test] \t [test] \t [test] \t [Column3] \t [Column4]

我想要做的是用整数重命名重复的列 [test]。 所以会变成类似

[Column1] \t [Column2] \t [test1] \t [test2] \t [test3] \t [test4] \t [Column3] \t [Column4]

到目前为止,我可以隔离第一行。然后数一下我找到的匹配项

string destinationUnformmatedFileName = @"C:\New\20130816_Opportunities_unFormatted.txt";
string destinationFormattedFileName = @"C:\New\20130816_Opportunities_Formatted.txt";
var unformattedFileStream = File.Open(destinationUnformmatedFileName, FileMode.Open, FileAccess.Read);  // Open (unformatted) file for reading
var formattedFileStream = File.Open(destinationFormattedFileName, FileMode.Create, FileAccess.Write);   // Create (formattedFile) for writing

StreamReader sr = new StreamReader(unformattedFileStream);
StreamWriter sw = new StreamWriter(formattedFileStream);

int rowCounter = 0;
// Read each row in the unformatted file
while ((currentRow = sr.ReadLine()) != null)
{
    //First row, lets check for duplicate names
    if (rowCounter = 0)
    {

    // Write column name to array
    string delimiter = "\t";
    string[] fieldNames = currentRow.Split(delimiter.ToCharArray());

    foreach (string fieldName in fieldNames)
    {
        // fieldName must be followed by a tab for it to be a duplicate
        // original code - causing the issue
        //Regex rgx = new Regex("\\t(" + fieldName + ")\\t");
        // Edit - resolved the issue
        Regex rgx = new Regex("(?<=\\t|^)(" + fieldName + ")(\\t)+");   

        // Count how many occurances of fieldName in currentRow
        int count = rgx.Matches(currentRow).Count;               
        //MessageBox.Show("Match Count = " + count.ToString());

        // If we have a duplicate field name 
        if (count > 1)                                           
        {
             string newFieldName = "\t" + fieldName + count.ToString() + "\t";
             //MessageBox.Show(newFieldName);
             currentRow = rgx.Replace(currentRow, newFieldName, 1);   
         }
     }
     }
rowCounter++;
}

我认为我在正确的轨道上,但我不认为正则表达式工作正常?

编辑:我想我已经知道如何使用 using 找到模式了;

Regex rgx = new Regex("(?<=\\t|^)(" + fieldName + ")(\\t)+"); 

这不是一个交易破坏者,但现在唯一的问题是它标签;

[Column1] \t [Column2] \t [test4] \t [test3] \t [test2] \t [test] \t [Column3] \t [Column4]

代替

[Column1] \t [Column2] \t [test1] \t [test2] \t [test3] \t [test4] \t [Column3] \t [Column4]

【问题讨论】:

  • “我不认为正则表达式工作正常”听起来你甚至不确定是否有问题。什么不工作?你有例外吗?错误的结果?没结果?此外,您可能希望对模式使用逐字字符串以避免双重转义:@"\t(。其次,您可能应该在将其连接成模式之前运行fieldNameRegex.Escape(),因为它可能包含元字符。
  • 关于您的编辑。如果这样可以解决问题,那么问题是匹配永远不会重叠。由于您在字段名称之前和之后需要 \t,因此相邻字段的匹配项会重叠。环视是一个很好的解决方案。另外,请将您的解决方案作为答案发布(如果没有更好的解决方案,请接受)。
  • 感谢 m.buettner - 我已经发布了答案,但需要等待 2 天才能接受。现在感觉不好浪费人们的时间应该等待更长的时间和更多的研究。感谢您的帮助!
  • 与论坛网站不同,我们不使用“谢谢”、“任何帮助表示赞赏”或Stack Overflow 上的签名。请参阅“Are taglines & signatures disallowed?”和“Should 'Hi', 'thanks,' taglines, and salutations be removed from posts?

标签: c# regex ssis


【解决方案1】:

首先在RegExr 测试您的正则表达式。我认为“\t”是一个特殊字符。试试“\\t”。 在您的 C# 中,它将是 "\\\\t"

【讨论】:

  • 他做到了,反正也没关系。正则表达式引擎可以处理实际的制表符以及转义的\t
【解决方案2】:

使用下面的

 Regex rgx = new Regex("(?<=\\t|^)(" + fieldName + ")(\\t)+"); 

通过使用我在此处找到的环视解决了问题; http://www.regular-expressions.info/duplicatelines.html

可能应该在发布前多花几分钟研究一下。

【讨论】:

    【解决方案3】:

    这是RegexLINQ 之间的伟大组合:

    var input = @"[Column1] \t [Column2] \t [test] \t [test] \t [test] \t [foo] \t [test] \t [Column3] \t [foo] \t [Column4]";
    Regex reg = new Regex(@"(?<=\\t )[[](.+?)[]]");
    string output = "";
    int k = 0;           
    foreach (var m in reg.Matches(input)
                         .OfType<Match>()
                         .Select((x,i)=>new {x,i})
                         .GroupBy(g=>g.x.Value)
                         .Where(g=>g.Count()>1)
                         .SelectMany(x=> x.Select((a,i)=>new {a,i=i+1}))
                         .OrderBy(x=>x.a.i)){                        
         output += input.Substring(k, m.a.x.Index - k) + m.a.x.Result("[${1}" + m.i + "]");
         k = m.a.x.Index + m.a.x.Length;
     }
     output += input.Substring(k);
    

    结果: [Column1] \t [Column2] \t [test1] \t [test2] \t [test3] \t [foo1] \t [test4] \t [Column3] \t [foo2] \t [Column4 ]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-16
      • 2014-06-18
      • 1970-01-01
      • 2022-12-11
      • 2014-11-20
      相关资源
      最近更新 更多