代码之家  ›  专栏  ›  技术社区  ›  polygenelubricants

使用regex编写bat separatethousands(和单元测试how-to)

  •  0
  • polygenelubricants  · 技术社区  · 15 年前

    这个问题是regex实践和单元测试实践的结合。

    正则表达式部分

    我写了这个问题 separateThousands 对于个人实践:

    给定一个数字作为字符串,引入逗号来分隔数千个数字。数字可以包含可选的减号和可选的小数部分。不会有多余的前导零。

    我的解决方案是:

    String separateThousands(String s) {
      return s.replaceAll(
          String.format("(?:%s)|(?:%s)",
            "(?<=\\G\\d{3})(?=\\d)",
            "(?<=^-?\\d{1,3})(?=(?:\\d{3})+(?!\\d))"
          ),
          ","
      );
    }
    

    它的工作方式是将两种类型的逗号分类,即 第一 休息 . 在上面的regex中, 休息 子模式实际上出现在 第一 . 匹配总是零长度,即 replaceAll 具有 "," .

    这个 休息 基本上是看后面是否有匹配,后面跟着3位数字,然后再看前面是否有数字。这是上一场比赛引发的某种连锁反应机制。

    这个 第一 基本上是在寻找 ^ 锚定,后跟可选减号,介于1到3位之间。从该点开始的字符串的其余部分必须匹配三位数,后跟一个非数字(可以是 $ \. )

    我的问题是:

    • 这个正则表达式可以简化吗?
    • 能否进一步优化?
      • 排序 休息 之前 第一 是故意的,因为 第一 只需要一次
      • 无捕获组

    单元测试部分

    正如我所提到的,我是 author 所以我也负责为他们设计测试用例。它们在这里:

    INPUT, OUTPUT
    "1000", "1,000"
    "-12345", "-12,345"
    "-1234567890.1234567890", "-1,234,567,890.1234567890"
    "123.456", "123.456"
    ".666666", ".666666"
    "0", "0"
    "123456789", "123,456,789"
    "1234.5678", "1,234.5678"
    "-55555.55555", "-55,555.55555"
    "0.123456789", "0.123456789"
    "123456.789", "123,456.789"
    

    我没有太多的工业实力单元测试经验,所以我想知道其他人是否可以评论这是否是一个很好的覆盖范围,我是否遗漏了任何重要的东西,等等(如果我遗漏了一个场景,我总是可以添加更多的测试)。

    2 回复  |  直到 10 年前
        1
  •  1
  •   Alan Moore Chris Ballance    15 年前

    这对我有效:

    return s.replaceAll("(\\G-?\\d{1,3})(?=(?:\\d{3})++(?!\\d))", "$1,");
    

    第一次通过, \G 作用与 ^ ,以及前方部队 \d{1,3} 只使用尽可能多的字符以使匹配位置保持在三位数的边界。之后, \{{1,3} 每次最多消耗三位数 g 把它固定在上一场比赛的末尾。

    至于您的单元测试,我只想在问题描述中明确指出,输入将始终是有效的数字,最多有一个小数点。

        2
  •  1
  •   nvuono    15 年前

    当你陈述这些要求时,你打算用你的方法来执行吗?

    该数字可以包含可选的 减号和可选小数 部分。不会有 多余的前导零。

    如果您的目的是让方法检测何时违反了这些约束,那么您将需要编写额外的单元测试来确保契约得到执行。

    测试一下怎么样 1234.5678.91011 ?

    您希望您的方法返回1234.5678.91011还是忽略整个过程? 最好写一个测试来验证你的期望