Подтвердить что ты не робот

Строка Ruby с регулярным выражением

Это Ruby 1.8.7, но должно быть таким же, как для 1.9.x

Я пытаюсь разбить строку, например:

a = "foo.bar.size.split('.').last"
# trying to split into ["foo", "bar","split('.')","last"]

В основном разбивая его на команды, которые он представляет, я пытаюсь сделать это с помощью Regexp, но не уверен, как идея заключалась в использовании regexp

a.split(/[a-z\(\)](\.)[a-z\(\)]/)

Здесь мы пытаемся использовать группу (\.), чтобы разделить ее, но это, кажется, не очень хороший подход.

4b9b3361

Ответ 1

Я думаю, что это сделало бы это:

a.split(/\.(?=[\w])/)

Я не знаю, как много вы знаете о регулярном выражении, но (?=[\w]) - это выражение, которое гласит, что "соответствует только точке, если следующий символ является символом буквы". Взгляд на самом деле не будет захватывать текст, который он соответствует. Это просто "выглядит". Таким образом, результат - именно то, что вы ищете:

> a.split(/\.(?=[\w])/)
 => ["foo", "bar", "size", "split('.')", "last"] 

Ответ 2

Я боюсь, что регулярные выражения не заставят вас очень далеко. Рассмотрим, например, следующие выражения (которые также являются действительными Ruby)

"(foo.bar.size.split( '.' )).last"
"(foo.bar.size.split '.').last"
"(foo.bar.size.split '( . ) . .(). .').last"

Проблема заключается в том, что список вызовов на самом деле является деревом вызовов. Самое простое решение в поле зрения - возможно, использовать парсер Ruby и преобразовать дерево разбора в соответствии с вашими потребностями (в этом примере мы рекурсивно спускаемся в дерево вызовов, собирая вызовы в список):

# gem install ruby_parser
# gem install awesome_print
require 'ruby_parser'
require 'ap'

def calls_as_list code
    tree = RubyParser.new.parse(code)

    t = tree
    calls = []

    while t
        # gather arguments if present
        args = nil
        if t[3][0] == :arglist
            args = t[3][1..-1].to_a
        end
        # append all information to our list
        calls << [t[2].to_s, args]
        # descend to next call
        t = t[1]
    end

    calls.reverse
end

p calls_as_list "foo.bar.size.split('.').last"
#=> [["foo", []], ["bar", []], ["size", []], ["split", [[:str, "."]]], ["last", []]]
p calls_as_list "puts 3, 4"
#=> [["puts", [[:lit, 3], [:lit, 4]]]]

И чтобы показать дерево разбора любого ввода:

ap RubyParser.new.parse("puts 3, 4")

Ответ 4

здесь у меня нет ruby ​​env. Я попытался с python re.split().

In : re.split("(?<!')\.(?!')",a)
Out: ['foo', 'bar', 'size', "split('.')", 'last']

в приведенном выше выражении есть отрицательный lookahead И, чтобы убедиться, что одиночная кавычка "точка" между не будет работать как разделитель.

конечно, для данного примера вам достаточно одного из lookbehind или lookahead. вы можете выбрать правильный путь для своих требований.