Как разделить строку на 2 части после определенной позиции

#ruby-on-rails #ruby

#ruby-on-rails #ruby

Вопрос:

Например, у меня есть какая-то случайная строка:

 str = "26723462345"
  

И я хочу разделить ее на 2 части после 6-го символа. Как это сделать правильно?

Спасибо!

Ответ №1:

Это должно сделать это

 [str[0..5], str[6..-1]]
  

или

  [str.slice(0..5), str.slice(6..-1)]
  

Действительно стоит проверить http://corelib.rubyonrails.org/classes/String.html

Комментарии:

1. или str[0 …6], и вы везде пишете ключевое значение «6»

Ответ №2:

Вот опция. Имейте в виду, однако, что это приведет к изменению вашей исходной строки:

 part1, part2 = str.slice!(0...6), str

p part1  # => "267234"
p part2  # => "62345"
p str    # => "62345"
  

Обновить

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

Предостережение: это будет работать только с символами ASCII.

 str.unpack("a6a*")
# => ["267234", "62345"]
  

В следующем используется переменная magic $' , которая возвращает часть строки после последнего совпадения регулярных выражений:

 part1, part2 = str[/.{6}/], $'
p [part1, part2]
# => ["267234", "62345"]
  

И этот последний использует lookbehind, чтобы разделить строку в нужном месте, не возвращая никаких дополнительных частей:

 p str.split(/(?<=^.{6})/)
# => ["267234", "62345"]
  

Комментарии:

1. Мне это нравится больше, чем у меня. Хотя я бы добавил str = part1 part2 в конце, чтобы строка не менялась.

2. Ну, если вы хотите сохранить str неизменным, то ваше решение лучше, я думаю.

3. Как насчет: str, part1, part2 = str.clone, str.slice! (0 ..6), str

4. Я не буду заходить так далеко, чтобы сказать, что функциональный стиль всегда лучше императивного стиля, но ИМХО это изменение на месте слишком умно, чтобы быть целесообразным.

Ответ №3:

Лучший способ IMO string.scan(/.{6}/)

 irb(main)> str
=> "abcdefghijklmnopqrstuvwxyz"
irb(main)> str.scan(/.{13}/)
=> ["abcdefghijklm", "nopqrstuvwxyz"]
  

Комментарии:

1. str.scan(/.{6}/) в примере OP возвращается только первая часть.

Ответ №4:

Комментарии:

1. Неплохо. Бонус: вы можете разделить так, чтобы последняя часть всегда состояла из 6 символов, подобных этому: part1, part2, _ = str.partition /.{6}$/

Ответ №5:

В качестве забавного ответа, как насчет:

 str.split(/(^.{1,6})/)[1..-1]
  

Это работает, потому что split возвращает совпадения группы захвата, в дополнение к частям строки до и после регулярного выражения.

Ответ №6:

Вот вам версия для повторного использования:

 str       = "26723462345"
n         = str.length
boundary  = 6
head      = str.slice(0, boundary) # => "267234" 
tail      = str.slice(boundary, n) # => "62345" 
  

Он также сохраняет исходную строку, которая может пригодиться позже в программе.

Комментарии:

1. Вы можете использовать -1 вместо того, чтобы получать длину строки.