Ruby Regex复数

时间:2017-09-12 22:41:10

标签: ruby regex

我有以下代码来测试复数:

module RegexPractice

  def get_complex(input)
    return input =~ /.*i*/
  end

end

代码应该通过下面的每个单元测试,但是我的单元测试#7开始失败。我不确定要解决这个问题的实施方案。有什么想法吗?

def test_complex

  #1
  assert_equal(0, RegexPractice.get_complex("4i"))
  #2
  assert_equal(0, RegexPractice.get_complex("43i"))
  #3
  assert_equal(0, RegexPractice.get_complex("-46i"))
  #4
  assert_equal(0, RegexPractice.get_complex("+46i"))
  #5
  assert_equal(0, RegexPractice.get_complex("35+46i"))
  #6
  assert_equal(0, RegexPractice.get_complex("3-46i"))
  #7
  assert_equal(5, RegexPractice.get_complex("num: -35+46i"))
  #8
  assert_equal(0, RegexPractice.get_complex("+3-46i"))
  #9
  assert_equal(nil, RegexPractice.get_complex("abi"))
  #10
  assert_equal(nil, RegexPractice.get_complex("65"))
end

2 个答案:

答案 0 :(得分:2)

你可以像这样实现它:

module RegexPractice

  def get_complex(input)
    input =~ /[+-]?\d*[+-]?\d*i/
  end

end

问题在于,您对i之前的内容不够严格,这是复数的一部分。

您当前的代码只是在i作为匹配的一部分之前说“包含任何”。因此,匹配总是从字符串的开头开始 - 因此该方法返回0(如果没有匹配则返回nil

解释我的正则表达式:

  • [+-]表示“+-字符。
  • [+-]?表示“零或一个以上”。
  • \d表示“任何数字”(0,1,2,...,9)。
  • \d*表示“以上零或更多”。

换句话说,这将匹配以下内容:

  • "42i"
  • "2-i"
  • "-3+9i"

不会匹配包含i的任意其他字符串。

您的测试#9和#10也会失败(但通过我的实现!) - 但您没有看到这一点,因为测试在第一次失败时终止。 (因此,将每个断言拆分为单独的测试会更好。)

assert_equal(nil, RegexPractice.get_complex("abi"))

您的方法将返回0,因为它仍匹配“i之后的任何内容”。

我的方法会返回nil,因为它只匹配“{”后跟i(例如-3+4i);不是任意字符。

assert_equal(nil, RegexPractice.get_complex("65"))

你的方法应该在这里工作,除了一个小错误:因为你的正则表达式以i*而不仅仅是i结束,它匹配“0或更多{{1 }} S”。换句话说,它仍会匹配包含i的字符串。

我的方法没有这个错误。

但是,通常情况下,如果要将字符串转换为复数,则可以执行以下操作:

i

...如果引发异常,则字符串格式无效。

Complex(string) 之类的输入通常无效;因此,如果您想接受这些,那么您确实需要先执行某种正则表达式查找。

答案 1 :(得分:1)

你的测试失败的原因是你可能正在测试错误的东西。

RegexPractice.get_complex("num: -35+46i") 假设返回0,因为您与之匹配的模式:

/.*i*/

返回0 or more of any character后跟0 or more i's完整匹配的第一个索引。

您可以使用Rubular来检查正则表达式匹配,也可以在控制台中运行它:

irb >>> "num: -35+46i" =~ /.*i/ => 0

如果您最终尝试在任何给定字符串中返回复数的第一个索引,则可能需要根据预期输入执行一些更复杂的模式匹配,即查找+或{{ 1}}在左边标有一个实数,在右边有一个复数。

最后,如果您只想创建复杂数字并与之互动,您可能需要参考this documentation.