【问题标题】:Regular expression replace in C#C#中的正则表达式替换
【发布时间】:2013-04-20 05:37:39
【问题描述】:

我对使用正则表达式还很陌生,并且根据我阅读过的一些教程,我无法在 Regex.Replace 中正确格式化这一步。

这是我正在处理的场景...当我从列表框中提取数据时,我想将其格式化为CSV 类似的格式,然后保存文件。使用替换选项是这种情况的理想解决方案吗?

在正则表达式格式化示例之前。

FirstName LastName Salary    Position
-------------------------------------
John      Smith    $100,000.00  M

正则表达式替换后的建议格式

John Smith,100000,M

当前格式化状态输出:

John,Smith,100000,M

*注意 - 有没有办法可以用空格替换第一个逗号?

我的代码片段

using(var fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write))
{
    using(var sw = new StreamWriter(fs))
    {
        foreach (string stw in listBox1.Items)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(stw);

            //Piecing the list back to the original format
            sb_trim = Regex.Replace(stw, @"[$,]", "");
            sb_trim = Regex.Replace(sb_trim, @"[.][0-9]+", "");
            sb_trim = Regex.Replace(sb_trim, @"\s", ",");
            sw.WriteLine(sb_trim);
        }
    }
}

【问题讨论】:

  • 用你的正则表达式44.66 将被替换为44
  • 刚刚重新编辑了我的声明...我将 100,000.00 转换为 100000。是的,当我写回 csv 格式时,我在这个等式中留下了美分。
  • 请尽量不要使用太多粗体 - 我已经删除了所有并修复了您不完整的 Dispose 调用,因此代码看起来没问题。
  • @Curtis 你应该使用[.]0+(?=\s) 然后
  • @Anirudh \.\d+ 会不会更好?也许它并不总是 0.00。

标签: c# regex


【解决方案1】:

你可以用两个替换来做到这一点

//let stw be "John Smith $100,000.00 M"

sb_trim = Regex.Replace(stw, @"\s+\$|\s+(?=\w+$)", ",");
//sb_trim becomes "John Smith,100,000.00,M"

sb_trim = Regex.Replace(sb_trim, @"(?<=\d),(?=\d)|[.]0+(?=,)", "");
//sb_trim becomes "John Smith,100000,M"

sw.WriteLine(sb_trim);

【讨论】:

  • 这确实做了很多不必要的工作,而且可能对性能不太好。如果你打算这样做,至少设置一个超时。
  • @Anirudh 我明白他想做什么。我在下面有一个单行答案,但我不确定它是否有效。
  • @Zenexer,每当使用正则表达式时,性能都会受到影响 - 是否重要完全取决于情境。
  • @Moo-Juice 当然是的,这就是为什么我更喜欢避免使用它们。使用它们时,最好预编译它们。
【解决方案2】:

试试这个::

sb_trim = Regex.Replace(stw, @"(\D+)\s+\$([\d,]+)\.\d+\s+(.)",
    m => string.Format(
        "{0},{1},{2}",
        m.Groups[1].Value,
        m.Groups[2].Value.Replace(",", string.Empty),
        m.Groups[3].Value));

这和你得到的答案一样干净,至少使用正则表达式。

  • (\D+):第一个捕获组。一个或多个非数字字符。
  • \s+\$:一个或多个空格字符,然后是文字美元符号 ($)。
  • ([\d,]+):第二个捕获组。一位或多位数字和/或逗号。
  • \.\d+:小数点,然后至少一位数字。
  • \s+:一个或多个空格字符。
  • (.):第三个捕获组。任何非换行符。

第二个捕获组还需要去掉逗号。您可以使用另一个正则表达式来执行此操作,但这确实是不必要的并且对性能不利。这就是为什么我们需要使用 lambda 表达式和字符串格式来拼凑替换。如果不是这样,我们可以用它来代替 lambda 表达式:

"$1,$2,$3"

【讨论】:

  • 谢谢,是的,我尝试对我的正则表达式进行分组,但是我似乎比任何事情都复杂,所以我回到了基础。我也会试一试。
  • 可能有一些方法可以避免组中的逗号,但它逃脱了我。这里肯定有人更熟悉 .NET 特定的正则表达式,所以也许他们会知道。
  • @Anirudh 不符合MSDN
  • 它是非捕获组,但您仍在另一个组中捕获它,即它仍会在 group2 中捕获...
  • 啊。用(?&lt;=)怎么样?
【解决方案3】:

添加以下两行

var regex = new Regex(Regex.Escape(","));
sb_trim = regex.Replace(sb_trim, " ", 1);

如果 sb_trim= John,Smith,100000,M 上面的代码将返回“John Smith,100000,M”

【讨论】:

    【解决方案4】:

    这必须做的工作:

    var result=Regex.Replace("John      Smith    $100,000.00  M", @"^(\w+)\s+(\w+)\s+\$([\d,\.]+)\s+(\w+)$","$1,$2,$3,$4");
    
    //result: "John,Smith,100,000.00,M"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-21
      • 2022-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多