web-dev-qa-db-fra.com

Comment diviser une chaîne en deux parties seulement, par la dernière occurrence du caractère divisé?

Par exemple:

"Angry Birds 2.4.1".split(" ", 2)
 => ["Angry", "Birds 2.4.1"] 

Comment puis-je scinder la chaîne en: ["Angry Birds", "2.4.1"]

37
ohho

String # rpartition , par ex.

irb(main):068:0> str = "Angry Birds 2.4.1"
=> "Angry Birds 2.4.1"
irb(main):069:0> str.rpartition(' ')
=> ["Angry Birds", " ", "2.4.1"]

Puisque la valeur renvoyée est un tableau, utiliser .first et .last permettrait de traiter le résultat comme s'il était divisé en deux, par exemple

irb(main):073:0> str.rpartition(' ').first
=> "Angry Birds"
irb(main):074:0> str.rpartition(' ').last
=> "2.4.1"
80
Vadym Tyemirov

J'ai une solution comme celle-ci:

class String
  def split_by_last(char=" ")
    pos = self.rindex(char)
    pos != nil ? [self[0...pos], self[pos+1..-1]] : [self]
  end
end

"Angry Birds 2.4.1".split_by_last  #=> ["Angry Birds", "2.4.1"]
"test".split_by_last               #=> ["test"]
9
halfelf

Certains aiment cela peut-être? Split où un espace est suivi de tout, sauf un espace jusqu'à la fin de la chaîne.

"Angry Birds 2.4.1".split(/ (?=\S+$)/)
#=> ["Angry Birds", "2.4.1"]
7
oldergod

C'est probablement trop compliqué (et probablement pas particulièrement efficace), mais vous pouvez le faire:

"Angry Birds 2.4.1".reverse.split(" ", 2).map(&:reverse).reverse
2
matthew.tuck

Je n'arrive pas à obtenir le code d'exemple dans mon commentaire correctement formaté. Je le soumets donc sous forme de réponse distincte, même si Vadym Tyemirov mérite tout le crédit de la solution String#rpartition fournie plus haut.

Je voulais juste ajouter que String#rpartition joue très bien avec la variable "ne se soucie pas" de Ruby, car vous n'êtes généralement intéressé que par le premier et le dernier élément du tableau de résultat, mais pas par l'élément intermédiaire (le séparateur):

[1] pry(main)> name, _, version = "Angry Birds 2.4.1".rpartition(' ')
=> ["Angry Birds", " ", "2.4.1"]
[2] pry(main)> name
=> "Angry Birds"
[3] pry(main)> version
=> "2.4.1"

Donc, pas besoin de Array#first ou Array#last... less is more! :-)

1
pvandenberk

La solution de partitionnement constitue un excellent one-liner sexy (j'ai voté pour), mais voici une autre technique si vous voulez un one-liner qui soit plus flexible pour résoudre des problèmes de partitionnement plus complexes: 

["Angry Birds 2.4.1".split(' ')[0..-2].join(' '), "Angry Birds 2.4.1".split(' ')[-1..-1].join(' ')]

Par plus flexible, je veux dire si plus d’objets étaient partitionnés, vous pourriez simplement ajuster la plage de la séquence.

1
jsarma
class String
  def divide_into_two_from_end(separator = ' ')
    self.split(separator)[-1].split().unshift(self.split(separator)[0..-2].join(separator))
  end
end

"Angry Birds 2.4.1".divide_into_two_from_end(' ') #=> ["Angry Birds", "2.4.1"]
0
Jing Li