【问题标题】:How to separate a string by perens without losing the perens? Ruby如何在不丢失 perens 的情况下用 perens 分隔字符串?红宝石
【发布时间】:2016-02-29 14:15:16
【问题描述】:

所以我试图解决一个挑战,如果 perens 的顺序正确,我会返回 true;否则,当然是错误的。我想出的代码在这里:

def valid_parentheses(str)
    return false if str.length % 2 == 1
        begin
            eval(str)
        rescue SyntaxError
            false
        else
            true
        end
    end
end

除了在valid_parentheses("hi(hi)()") 这样的情况下,它应该返回# => true,而是返回false,因为结尾() 是不必要的引用-取消引用,因此会引发错误。

我试图用括号把它分开,但是:

str.split(/\(.*\))
# =>"hi"

因为它删除了所有的括号,并且:

str.scan(/\(.*\))
#=> "(hi)()"

因为从技术上讲,它仍然以( 开头并以) 结尾。

如何将其拆分为分别得到 "(hi)""()"

【问题讨论】:

  • 你能清楚地解释一下你想用一个或几个示例输入字符串实现什么以及相应的预期结果吗?如果我理解得很好,您想检查括号是否平衡,不是吗?我已经可以说split 方法不是可行的方法。为什么这个奇怪的测试return false if str.length % 2 == 1(注意== 1没用,不用取模,可以检查最后一位)

标签: ruby regex string


【解决方案1】:

有几种方法可以做到这一点。一种是首先删除除"("")" 之外的所有字符,然后在循环中删除子字符串"()",继续直到无法删除更多这样的对。如果字符串为空,则括号是平衡的;否则他们不是。

def balanced_parens?(str)
  pstr = str.gsub(/[^()]/,"")
  puts "pstr=#{pstr}"
  while pstr.gsub!("()", "")
  end
  pstr.empty?
end

balanced_parens? "Now (is(the(time)to(have(fun)))fun)"
  #=> true
balanced_parens? "Now (is(the)time)to(have)fun)((fun)"
  #=> false

以下是这两个字符串的分步说明:

str = "Now (is(the(time)to(have(fun)))fun)"
pstr = str.gsub(/[^()]/,"")
  #=> "((()(())))" 
pstr.gsub!("()", "")
  #=> "((()))" 
pstr.gsub!("()", "")
  #=> "(())" 
pstr.gsub!("()", "")
  #=> "()" 
pstr.gsub!("()", "")
  #=> "" 
pstr.gsub!("()", "")
  #=> nil 
pstr.empty?
  #=> true

str = "Now (is(the)time)to(have)fun)((fun)"
pstr = str.gsub(/[^()]/,"")
  #=> "(())())(()" 
pstr.gsub!("()", "")
  #=> "())(" 
pstr.gsub!("()", "")
  #=> ")(" 
pstr.gsub!("()", "")
  #=> nil 
pstr.empty?
  #=> false

【讨论】:

    【解决方案2】:

    你已经接近你想要的了。如果我正确理解您的问题,这是我将使用的正则表达式:

    (\(.*?\))
    
    \(      // match the left bracket
    .*?     // match any character as FEW times as possible (lazy use of * because of the ?)
    \)      // match the right bracket
    

    Regex Demo

    确实,由于惰性模式,给定字符的搜索将在最后一个使用的字符之后开始。

    • X* 从行尾开始搜索(greedy
    • X*? 在最后使用的字符之后立即开始搜索(lazy
    • X*+ 就像贪心量词,只是它不会回溯

    @Anomie 在这里解释一下:Greedy vs. Reluctant vs. Possessive Quantifiers

    【讨论】:

      【解决方案3】:

      您是否考虑过使用正则表达式? 比如:

      /hay/ =~ 'haystack'   #=> 0
      /y/.match('haystack') #=> #<MatchData "y">
      

      可能会起作用。

      【讨论】:

      • 刚刚试过,其实。如果我不考虑其他字符(例如/\(\)/.match(str)),它会给我“()”,但如果我像上面显示的那样,我仍然会得到“(hi)()”。谢谢你
      猜你喜欢
      • 2017-05-29
      • 2016-11-24
      • 1970-01-01
      • 1970-01-01
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 2014-06-11
      • 2014-02-11
      相关资源
      最近更新 更多