Como dividir strings em Ruby

A menos que a entrada do usuário seja uma única palavra ou número, essa entrada precisará ser Dividido ou transformado em uma lista de strings ou números.

Por exemplo, se um programa solicitar seu nome completo, incluindo a inicial do meio, primeiro será necessário dividir essa entrada em três cordas antes que ele possa trabalhar com seu nome, meio e sobrenome individuais. Isso é alcançado usando o String # split método.

Como String # split funciona

Na sua forma mais básica, String # split usa um único argumento: o delimitador de campo como uma sequência. Esse delimitador será removido da saída e uma matriz de seqüências de caracteres dividida no delimitador será retornada.

Portanto, no exemplo a seguir, assumindo que o usuário inseriu o nome corretamente, você deve receber um elemento de três elementos Matriz da divisão.

#! / usr / bin / env ruby
print "Qual é o seu nome completo? "
full_name = gets.chomp
nome = full_name.split ('')
coloca "Seu primeiro nome é # {name.first}"
coloca "Seu sobrenome é # {name.last}"
instagram viewer

Se executarmos este programa e inserirmos um nome, obteremos alguns resultados esperados. Observe também que nome primeiro e nomear última são coincidências. o nome variável será uma Matriz, e essas duas chamadas de método serão equivalentes a nome [0] e nome [-1] respectivamente.

$ ruby ​​split.rb
Qual seu nome completo? Michael C. Morin
Seu primeiro nome é Michael
Seu sobrenome é Morin

Contudo, String # split é um pouco mais inteligente do que você imagina. Se o argumento para String # split é uma string, ela realmente o usa como delimitador, mas se o argumento for uma string com um único espaço (como usamos), deduz que você deseja dividir em qualquer quantidade de espaço em branco e que também deseja remover qualquer espaço em branco inicial.

Então, se formos dar alguma entrada ligeiramente malformada, como

Michael C. Morin

(com espaços extras), então String # split ainda faria o que é esperado. No entanto, esse é o único caso especial quando você passa por um Corda como o primeiro argumento. Delimitadores de expressões regulares

Você também pode passar uma expressão regular como o primeiro argumento. Aqui, String # split torna-se um pouco mais flexível. Também podemos tornar nosso código de divisão de nomes um pouco mais inteligente.

Não queremos o período no final da inicial do meio. Sabemos que é uma inicial do meio, e o banco de dados não vai querer um período lá, então podemos removê-lo enquanto nos dividimos. Quando String # split corresponde a uma expressão regular, faz exatamente a mesma coisa como se tivesse acabado de corresponder a um delimitador de string: tira-o da saída e divide-o nesse ponto.

Assim, podemos evoluir um pouco o nosso exemplo:

$ cat split.rb
#! / usr / bin / env ruby
print "Qual é o seu nome completo? "
full_name = gets.chomp
nome = full_name.split (/ \.? \ s + /)
coloca "Seu primeiro nome é # {name.first}"
coloca "Sua inicial do meio é # {name [1]}"
coloca "Seu sobrenome é # {name.last}"

Separador de registros padrão

Rubi não é muito bom em "variáveis ​​especiais" que você pode encontrar em idiomas como Perl, mas String # split usa um que você precisa estar ciente. Essa é a variável separadora de registro padrão, também conhecida como $;.

É global, algo que você não costuma ver no Ruby; portanto, se você o alterar, poderá afetar outras partes do código - apenas altere-o novamente quando terminar.

No entanto, tudo o que essa variável faz é atuar como o valor padrão para o primeiro argumento String # split. Por padrão, essa variável parece estar definida como nada. No entanto, se String # splitO primeiro argumento de nada, ele será substituído por uma única cadeia de espaço.

Delimitadores de comprimento zero

Se o delimitador passou para String # split é uma string de comprimento zero ou expressão regular, então String # split agirá um pouco diferente. Ele não removerá nada da string original e será dividido em todos os caracteres. Isso basicamente transforma a cadeia de caracteres em uma matriz de comprimento igual, contendo apenas cadeias de um caractere, uma para cada caractere da cadeia.

Isso pode ser útil para iterar sobre a cadeia de caracteres e foi usado em versões anteriores a 1.9.xe anteriores a 1.8.7 (que número de recursos de 1.9.x) para iterar sobre caracteres em uma sequência sem se preocupar em dividir byte múltiplo Caracteres Unicode. No entanto, se o que você realmente deseja fazer é iterar sobre uma string, e você estiver usando 1.8.7 ou 1.9.x, provavelmente deverá usar String # each_char em vez de.

#! / usr / bin / env ruby
str = "Ela me transformou em um tritão!"
str.split (''). cada um faz | c |
coloca c
fim

Limitando o comprimento da matriz retornada

Então, voltando ao nosso exemplo de análise de nome, e se alguém tiver um espaço em seu sobrenome? Por exemplo, sobrenomes holandeses geralmente podem começar com "van" (significando "de" ou "de").

Nós realmente queremos apenas um elemento 3 matriz, para que possamos usar o segundo argumento para String # split que até agora ignoramos. O segundo argumento deve ser um Fixnum. Se esse argumento for positivo, no máximo, muitos elementos serão preenchidos na matriz. Portanto, no nosso caso, gostaríamos de passar 3 para esse argumento.

#! / usr / bin / env ruby
print "Qual é o seu nome completo? "
full_name = gets.chomp
nome = full_name.split (/ \.? \ s + /, 3)
coloca "Seu primeiro nome é # {name.first}"
coloca "Sua inicial do meio é # {name [1]}"
coloca "Seu sobrenome é # {name.last}"

Se executarmos isso novamente e dermos um nome holandês, ele funcionará como esperado.

$ ruby ​​split.rb
Qual seu nome completo? Vincent Willem van Gogh
Seu primeiro nome é Vincent
Sua inicial do meio é Willem
Seu sobrenome é van Gogh

No entanto, se esse argumento for negativo (qualquer número negativo), não haverá limite para o número de elementos na matriz de saída e quaisquer delimitadores à direita aparecerão como cadeias de comprimento zero no final do array.

Isso é demonstrado neste trecho de IRB:

: 001> "isto, é, a, teste" .split (',', -1)
=> ["isto", "é", "a", "teste", "", "", "", ""]
instagram story viewer