2016-02-27 1 views
-1

Итак, я пытаюсь решить проблему, если, если perens находятся в правильном порядке, я вернусь к истине; иначе, конечно, ложно. Код я придумал здесь:Как отделить строку perens без потери perens? Ruby

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, потому что окончание () являются цитата-Unquote ненужными и, следовательно, вызывает ошибку.

Я попытался разбить его в круглые скобки, но:

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

, потому что он удалил все скобки, а также:

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

, потому что до сих пор технически начинается с ( и заканчивается ).

Как разделить это, чтобы получить "(hi)" и "()" отдельно?

+0

Не могли бы вы объяснить, ясно, что вы хотите достичь с помощью одного или нескольких примеров входных строк и соответствующих ожидаемых результатов? Если я хорошо понимаю, вы хотите проверить, сбалансированы ли скобки, не так ли? Я уже могу сказать, что метод 'split' - это не путь. И почему этот странный тест 'return false if str.length% 2 == 1'? * (обратите внимание, что '== 1' бесполезен, и вместо использования модуля вы можете проверить последний бит) * –

ответ

0

Есть несколько способов сделать это. Первый заключается в том, чтобы сначала удалить все символы, отличные от "(", и ")", а затем в цикле удалить подстроки "()", продолжая до тех пор, пока не удастся удалить такие пары. Если строка пуста, то парны сбалансированы; иначе они не будут.

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 
-1

Считаете ли вы использование регулярного выражения? Нечто вроде:

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

может работать.

+0

Просто попробовал, на самом деле. Если я не учитываю других символов (например, '/ \ (\) /. Match (str)'), он дает мне «()», но если я сделаю то, что я показал выше, я все равно получаю «(привет))». Спасибо, что –

0

Вы находитесь рядом с тем, что хотите. Вот регулярное выражение я хотел бы использовать, если я правильно понял ваш вопрос:

(\(.*?\)) 

\(  // 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*? начать поиск сразу после последнего потребляются персонаж (ленивым)
  • X*+ походит жадный квантор, за исключением того, что он не возвращается

@Anomie объяснить здесь: Greedy vs. Reluctant vs. Possessive Quantifiers

Смежные вопросы