【问题标题】:Removing commas from numbers with .NET regex使用 .NET 正则表达式从数字中删除逗号
【发布时间】:2018-07-07 17:19:24
【问题描述】:

所以我正在处理一份报告,该报告(非常棒,真的)在 .csv 输出中吐出带有逗号的数值。超级好用。

所以,我使用 (C#) 正则表达式前瞻正向和后向正向表达式来删除两边都有数字的逗号。

如果我只使用前瞻,它似乎工作。但是,当我也添加后视功能时,表达式会分解并且不会删除任何内容。逗号的两端可以有任意数量的数字,所以如果模式周围有一个或多个数字,我只想删除逗号。

这是仅适用于前瞻的表达式:

str = Regex.Replace(str, @"[,](?=(\d+)),"");

这里的表达方式不符合我的预期:

str = Regex.Replace(str, @"[,](?=(\d+)?<=(\d+))", "");

我的正则表达式有什么问题!如果我不得不猜测,那么我对lookbehind的工作方式有一些误解。有什么想法吗?

【问题讨论】:

  • 我不知道,但我建议Regex.Replace(str, @"(\d),(\d)", "$1$2")
  • 你怎么知道1,2,3,41, 2, 3, 41.2, 3.41, 2.3, 4或其他组合?
  • 我同意安德烈亚斯的观点。这种模棱两可意味着你需要解决最初的问题。创建 CSV 文件的东西实际上并没有创建有效的 CSV 文件,因为它应该引用包含逗号的值。如果你不能解决这个问题,也许你可以通过在使用点作为小数点的语言环境中运行它来欺骗它。
  • 您可以尝试Regex.Replace(s, @"(?&lt;=\d),(?=\d)", string.Empty),但似乎原来的方法可能需要重新考虑。
  • 如果你能展示一个示例输入和所需的输出会有所帮助

标签: c# regex


【解决方案1】:

您可以使用以下任何一种解决方案:

var s = "abc,def,2,100,xyz!,:))))";
Console.WriteLine(Regex.Replace(s, @"(\d),(\d)", "$1$2"));   // Does not handle 1,2,3,4 cases
Console.WriteLine(Regex.Replace(s, @"(\d),(?=\d)", "$1"));   // Handles consecutive matches with capturing group+backreference/lookahead
Console.WriteLine(Regex.Replace(s, @"(?<=\d),(?=\d)", ""));  // Handles consecutive matches with lookbehind/lookahead, the most efficient way
Console.WriteLine(Regex.Replace(s, @",(?<=\d,)(?=\d)", "")); // Also handles all cases

请参阅C# demo

解释

  • (\d),(\d) - 匹配并捕获 ,$1$2 两侧的单个数字是替换反向引用,将捕获的文本插入回结果中
  • (\d),(?=\d) - 匹配并捕获, 之前的一个数字,然后匹配一个逗号,然后正向前瞻(?=\d) 需要, 之后的一个数字,但由于它没有被消耗,因此在替换模式
  • (?&lt;=\d),(?=\d) - 只有这样的逗号匹配,它用数字括起来而不消耗数字((?&lt;=\d) 是一个正向的后视,需要它的模式匹配到当前位置的左侧)
  • ,(?&lt;=\d,)(?=\d) - 匹配逗号,只有在匹配后,正则表达式引擎才会检查位置之前是否有数字和逗号(即在逗号之后),如果检查为真,则检查下一个字符一个数字。如果是数字,则返回匹配项。

RegexHero.net测试:

奖金

您可以将类似您的模式与\d,\d 匹配并将匹配传递给MatchEvaluator method,您可以在其中进一步操作匹配:

Console.WriteLine(Regex.Replace(s, @"\d,\d", m => m.Value.Replace(",",string.Empty))); // Callback method

这里,m 是匹配对象,m.Value 保存整个匹配值。使用.Replace(",",string.Empty),您可以从匹配值中删除所有逗号。

【讨论】:

  • 很棒的答案,解释得很好。谢谢!
【解决方案2】:

您可以随时查看评估正则表达式的网站。 我认为这段代码可能会对您有所帮助:

str = Regex.Replace(str, @"[,](?=(\d+))(?<=(\d))", "");

【讨论】:

    猜你喜欢
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-21
    相关资源
    最近更新 更多