Строка 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\(\)]/)
Здесь мы пытаемся использовать группу (\.)
, чтобы разделить ее, но это, кажется, не очень хороший подход.
Ответы
Ответ 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")
Ответ 3
a = "foo.bar.size.split('.').last"
p a.split(/(?<!')\.(?!')/)
#=> ["foo", "bar", "size", "split('.')", "last"]
Вы ищете утверждения Lookahead и Lookbehind.
http://www.regular-expressions.info/lookaround.html
Ответ 4
здесь у меня нет ruby env. Я попытался с python re.split().
In : re.split("(?<!')\.(?!')",a)
Out: ['foo', 'bar', 'size', "split('.')", 'last']
в приведенном выше выражении есть отрицательный lookahead И, чтобы убедиться, что одиночная кавычка "точка" между не будет работать как разделитель.
конечно, для данного примера вам достаточно одного из lookbehind или lookahead. вы можете выбрать правильный путь для своих требований.