【问题标题】:C# regex to match exact number (including integers and decimals)C# 正则表达式匹配精确数字(包括整数和小数)
【发布时间】:2019-03-28 10:37:33
【问题描述】:

总结

我正在尝试使用正则表达式来匹配较大字符串中的确切数字(即人类可以理解的数字,而不是数字本身)。我尝试匹配的数字会有所不同。可以是整数,也可以是小数,也可以是一位数,也可以是多位数。

示例

  • 如果尝试匹配数字 2,我希望它在 x + 2 + 3 中找到 2,但不在 2.52.525.2 中找到 2(因为那是数字 2,而不是实际数字 2)。
  • 如果尝试匹配数字 2.5,我希望它在 x + 2.5 + 32.5 中找到 2.5,但不是 2.5212.5

请注意,2 和 2.5 只是示例,我希望它适用于任意正数(如果它适用于负数,这不是问题,但也不是必需的)。

初步尝试

我从 (\bX\b)+ 开始(其中 X 将是我要匹配的数字),当 X 为 2.5 时有效,但当 X 为 2 时无效。这是因为它使用分词符来识别数字,但小数点算作分词。这意味着如果 X 为 2(即正则表达式为 (\b2\b)+),它将匹配数字 2(正确),但也匹配 2.x(不正确)和 x.2(也不正确)。

当前尝试

我通过将表达式更改为(\bX\b(?!\.))+ 解决了2.x 的问题。这不包括 X 后跟小数点的数字,因此如果 X 为 2,它将匹配 2(正确),将不匹配 2.x(正确)但仍将匹配 x.2(不正确)。如果 X 是十进制数,则它可以正常工作(因此,如果 X 为 2.5,它将正确匹配 2.5 并排除 12.52.51)。

如果 X 前面有小数点,如何避免匹配?

实际用例

如果有帮助,最终目标是将其与 C# Regex.Replace 函数一起使用,如下所示:

private static string ReplaceNumberWithinFormula(string originalFormula, double numberToReplace, string textToReplaceNumberWith)
{
    return Regex.Replace(originalFormula, $@"(\b{numberToReplace}\b(?!\.))+", textToReplaceNumberWith);
}

【问题讨论】:

  • 请注意,您必须Regex.Escape numberToReplace 因为它可能包含.
  • 好地方,谢谢@WiktorStribiżew
  • @Tim 你尝试过我发布的解决方案吗?你能告诉我它为什么不符合你的要求吗?
  • @Saksham 没有必要尝试,Tim 不想提取/删除 任何 个数字,Tim 想替换传递的 特定 个数字到ReplaceNumberWithinFormula 方法

标签: c# regex


【解决方案1】:

你可以使用

private static string ReplaceNumberWithinFormula(string originalFormula, double numberToReplace, string textToReplaceNumberWith)
{
    return Regex.Replace(originalFormula, $@"(?<!\d\.?){Regex.Escape(numberToReplace.ToString())}(?!\.?\d)", textToReplaceNumberWith);
}

C# demo

(?&lt;!\d\.?){Regex.Escape(numberToReplace.ToString())}(?!\.?\d),假设里面的变量等于2.5,转换成(?&lt;!\d\.?)2\.5(?!\.?\d)并且匹配2.5只有当

  • (?&lt;!\d\.?) - 前面没有数字和可选的.
  • (?!\.?\d) - 后面没有可选的 . 和数字。

请参阅regex demo

一个更简单的正则表达式可以像你一样使用输入可以是一个词边界+基于环视的模式

private static string ReplaceNumberWithinFormula(string originalFormula, double numberToReplace, string textToReplaceNumberWith)
{
    return Regex.Replace(originalFormula, $@"\b(?<!\.){Regex.Escape(numberToReplace.ToString())}\b(?!\.)", textToReplaceNumberWith);
}

这里,正则表达式看起来像\b(?&lt;!\.)2\.5\b(?!\.),首先匹配单词边界位置(\b),然后确保在位置之前没有.(?&lt;!\.)),然后将匹配2.5,确保数字后面没有字符(字母、数字或_),然后检查数字后面是否没有.。见this regex demo

它等于$@"(?&lt;![\w.]){Regex.Escape(numberToReplace.ToString())}(?![\w.])",并且比允许您在任何上下文中匹配精确的浮点数或整数的顶级解决方案更具限制性

【讨论】:

    【解决方案2】:

    还添加一个负面的后视:

    ((?<!\.)\b2\b(?!\.))+
    

    检查demo

    【讨论】:

      【解决方案3】:

      我想这就是你要找的东西

      ^\d+(\.\d+)?\b
      
      • 这匹配整数,如 2

      • 匹配十进制数,如 2.1

      • 与 2. 或 .3 等模式不匹配

      【讨论】:

      • 谢谢你,但我认为你误解了我要解决的问题(对不起,如果我的解释不清楚,我很难说清楚!)在使用正则表达式时,我将有一个我想要匹配的特定数字,而不是试图识别字符串的哪些部分是数字。
      • @Tim 好吧,至少它不值得投反对票。
      猜你喜欢
      • 2021-11-10
      • 1970-01-01
      • 2012-06-10
      • 1970-01-01
      • 1970-01-01
      • 2020-05-04
      • 1970-01-01
      相关资源
      最近更新 更多