Как работать со строками в Ruby

Введение

A string is a sequence of one or more characters that may consist of letters, numbers, or symbols.

Строки в Ruby являются объектами, и, в отличие от других языков, строки изменяемы, что означает, что их можно изменять на месте, а не создавать новые строки.

Вы будете использовать строки в практически каждой программе, которую напишете. Строки позволяют отображать и взаимодействовать с пользователями с помощью текста. Фактически, страница, которую вы сейчас читаете, состоит из строк, отображаемых на вашем экране через ваш веб-браузер. Строки являются одним из самых важных фундаментальных элементов программирования.

В этом руководстве вы узнаете, как работать со строками в Ruby. Вы будете создавать строки, отображать их на экране, сохранять их в переменных, объединять несколько строк вместе и узнаете, как обрабатывать специальные символы, такие как переводы строк, апострофы и двойные кавычки.

Создание и вывод строк

Строки существуют либо в одинарных кавычках ', либо в двойных кавычках " в Ruby, поэтому для создания строки заключите последовательность символов в один из них:

'This is a string in single quotes.'

"This is a string in double quotes."

Можно выбирать использование как одинарных, так и двойных кавычек. В большинстве случаев это не имеет значения, главное — быть последовательным. Однако использование двойных кавычек позволяет выполнять интерполяцию строк, о которой вы узнаете в этом уроке.

Для отображения строки в вашей программе вы можете использовать метод print:

print "Let's print out this string."

Метод print выводит строку точно так, как она записана.

Попробуйте сами. Создайте новую программу на Ruby с названием print.rb с помощью вашего текстового редактора и используйте метод print, чтобы напечатать три строки:

print.rb
print 'This is the first string.'
print 'This is the second string.'
print 'This is the third string.'

Сохраните файл и запустите программу:

  1. ruby print.rb

Вы увидите следующий вывод:

Output
This is the first string.This is the second string.This is the third string.

Вместо того чтобы три строки печатались на отдельных строках, все три строки были напечатаны вместе на одной строке. Метод print выводит строку на экран, но если вы хотите, чтобы каждая строка находилась на своей строке, вам придется добавить символ переноса строки самостоятельно.

Если вы хотите, чтобы все три строки находились на отдельных строках, вместо этого используйте метод puts. Измените свою программу, чтобы использовать puts вместо print:

print.rb
puts 'This is the first string.'
puts 'This is the second string.'
puts 'This is the third string.'

Теперь запустите программу снова, и вы увидите этот вывод:

Output
This is the first string. This is the second string. This is the third string.

Метод puts выводит указанную строку, но также добавляет символ новой строки в конец строки за вас.

Хранение строк в переменных

Переменные – это именованные ссылки на место в памяти компьютера. Вы используете переменные для хранения данных и их последующего извлечения.

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

my_string = 'This is my string'

Затем, чтобы извлечь значение, используйте имя переменной:

print my_string

Чтобы проверить это самостоятельно, создайте файл string_variables.rb в вашем редакторе с помощью следующей команды:

  1. nano string_variables.rb

Затем добавьте следующий код:

string_variables.rb
my_name = "Sammy the Shark"
my_age = "none of your business"

puts my_name
puts my_age

Эта программа определяет две переменные: my_name и my_age. Каждой переменной присваивается строка. Затем мы используем метод puts, чтобы вывести каждую строку на отдельной строке.

Сохраните файл с помощью CTRL + X и y, затем выполните программу:

  1. ruby string_variables.rb

Вы увидите следующий вывод:

Output
Sammy the Shark none of your business

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

Давайте посмотрим, как объединить строки вместе, чтобы создать новые строки.

Конкатенация строк

Конкатенация означает объединение двух или более строк для создания новой строки. Для конкатенации мы используем оператор конкатенации, представленный символом +. Символ + также является оператором сложения при использовании в арифметических операциях.

Вот как можно объединить строки sammy и shark:

"sammy" + "shark"

Это приведет к следующему результату:

Output
sammyshark

Конкатенация объединяет строки друг за другом, объединяя их и выводя новое значение строки. Если вы хотите иметь пробел между словами sammy и shark, вам нужно включить этот пробел в одну из строк, вот так:

"sammy " + "shark"

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

Вот пример:

color = "Blue"
print "My favorite color is " + color

Это приведет к выводу Мой любимый цвет - синий. Обратите внимание, что мы оставили пробел после слова is в строке, чтобы в выводе был пробел между строкой и значением переменной.

Вы можете объединять несколько строк таким образом. Создайте файл concatenation.rb и добавьте этот код:

concatenation.rb
my_name = "Sammy the Shark"
my_age = "none of your business"

puts "My name is " + my_name + " and my age is " + my_age + "."

Эта программа определяет две переменные: my_name и my_age, каждая с назначенной строкой, как вы делали раньше. Но на этот раз, вместо печати значений, мы выводим строку, использующую конкатенацию для печати этих значений с дополнительным контекстом.

Когда вы запускаете эту программу, вы увидите следующий вывод:

Output
My name is Sammy the Shark and my age is none of your business.

В этой небольшой программе вы использовали конкатенацию для вставки переменных в эту строку.

Когда вы объединяете две или более строки через конкатенацию, вы создаете новую строку, которую можете использовать во всей программе, поэтому вам может захотеться присвоить созданную строку новой переменной, которую вы сможете использовать позже:

concatenation.rb
my_name = "Sammy the Shark"
my_age = "none of your business"

# присвоить сконкатенированную строку переменной
output = "My name is " + my_name + " and my age is " + my_age + "."

# Вывести результат.
puts output

В небольшой программе, подобной этой, использование дополнительной переменной output вероятно, излишне. Но в более крупных программах может возникнуть желание создать строку с использованием конкатенации, которую вы будете использовать в нескольких местах. Также хорошей привычкой является разделение обработки данных, таких как конкатенация и арифметика, от вывода, так как в конечном итоге ваши программы станут крупнее, и вам захочется разделить логику и вывод на отдельные файлы или компоненты, чтобы облегчить их управление.

Обязательно не используйте оператор + между двумя разными типами данных. Например, вы не можете конкатенировать строки и целые числа вместе.

Чтобы увидеть, что происходит, создайте новую программу с именем strings_and_integers.rb со следующим содержимым:

strings_and_integers.rb
my_name = "Sammy the Shark"
my_number = 27

print my_name + my_number

На этот раз у нас есть переменная my_name, которая содержит строку Sammy the Shark, и переменная my_number, которая содержит целое число 27. Мы знаем, что 27 не является строкой, потому что он не окружен кавычками. Он также не имеет десятичной точки, поэтому мы знаем, что это целое число.

Если вы запустите программу:

  1. ruby strings_and_ints.rb

Вы увидите это сообщение об ошибке:

Output
strings_and_ints.rb:4:in `+': no implicit conversion of Integer into String (TypeError) from strings_and_ints.rb:4:in `<main>'

Ошибка no implicit conversion of Integer into String означает, что Ruby может конкатенировать только строку с уже существующей строкой.

В версии Ruby 2.3 и ниже вы видели бы вместо этого сообщение об ошибке:

strings_and_ints.rb:4:in `+': no implicit conversion of Fixnum into String (TypeError)
from strings_and_ints.rb:4:in `<main>'

Ключевое слово Fixnum было типом данных, предоставленным целым числам в предыдущих версиях Ruby. Это сокращение от Fixed Number. В Ruby 2.4 Fixnum и его аналог Bignum больше не существуют и вместо них используется Integer.

Мы могли бы изменить нашу программу и поместить число 27 в кавычки ("27"), чтобы оно было объявлено как строка, а не как целое число. Или мы можем преобразовать число в строку при создании строки, так:

strings_and_integers.rb
my_name = "Sammy the Shark"
my_number = 27

print my_name + my_number.to_s

Метод .to_s преобразует целое число в строку. Это более правильный подход, поскольку он позволяет нам сохранить наше число как целое в нашей программе. Нам нужно, чтобы оно было строкой только при выводе на экран, но мы можем захотеть, чтобы оно было целым числом, если мы будем использовать его в других частях логики программы.

Запустите программу снова, и вы увидите, что на экране напечатано Sammy the Shark27.

Преобразование чисел в строки для конкатенации – это что-то, с чем вы часто сталкиваетесь, когда работаете с почтовыми кодами, валютой, номерами телефонов и другими числовыми данными, которые вы хотите отобразить на экране наряду с текстом.

Конкатенация мощна, но её использование может быть запутанным. Если вы случайно пропустите один из операторов +, это может вызвать синтаксическую ошибку. И если вам нужно объединить строки с переменными, содержащими числа, вы должны преобразовать переменные в строки. Ruby предоставляет ещё один способ вставки значений переменных в строку, называемый интерполяция строк, который решает оба эти проблемы.

Использование интерполяции строк

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

Вместо того чтобы писать так:

"My name is " + my_name + "!"

Вы можете сделать так:

"My name is #{my_name}!"

Вместо завершения строки и использования оператора +, вы заключаете переменную в синтаксис #{}. Этот синтаксис говорит Ruby вычислить выражение и вставить его в строку.

Попробуйте сами. Создайте новую программу с именем interpolation.rb и добавьте этот код:

interpolation.rb
my_name = "Sammy the Shark"
my_age = "none of your business"

output = "My name is #{my_name} and my age is #{my_age}."

puts output

Это та же программа, которую вы уже написали, но на этот раз мы используем интерполяцию строк для создания вывода.

Интерполяция строк имеет ещё одно преимущество: она может автоматически преобразовывать числовые значения в строки. Помните вашу программу strings_and_integers.rb? Откройте этот файл снова в вашем редакторе, но измените последнюю строку так, чтобы она выглядела следующим образом:

strings_and_integers.rb
my_name = "Sammy the Shark"
my_number = 27

# используйте интерполяцию вместо конкатенации
print "My name is #{my_name} and my favorite number is #{my_number}."

Руби автоматически преобразует my_number в строку, и ваша программа выведет следующий результат при запуске:

Output
My name is Sammy the Shark and my favorite number is 27.

Интерполяция строк мощная и удобная. Это также предпочтительный метод для объединения строк с переменными.

Строковые литералы и значения строк

Обратите внимание, что все созданные вами строки заключены в кавычки в коде, но фактический вывод не включает кавычки.

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

Это строковый литерал:

"Sammy the Shark"

Значение строки будет Sammy the Shark.

В большинстве случаев вам не придется беспокоиться о этом различии, если вы не хотите использовать специальные символы, такие как кавычки или апострофы, в ваших строках.

Экранирование кавычек и апострофов в строках

Из-за того, что кавычки используются для обозначения строк, вам придется немного больше поработать, если вы хотите использовать апострофы и кавычки в строках.

Если вы попытаетесь использовать апостроф посередине строк, заключенных в одинарные кавычки, вот так:

'This isn't what I wanted.'

Апостроф в isn't завершает строку, как вы можете видеть по странному подсвечиванию в этом примере. В результате интерпретатор Ruby попытается проанализировать оставшуюся часть предполагаемой строки как код, и вы получите ошибку.

Вы столкнетесь с такой же ситуацией, если используете двойные кавычки в строке, заключенной в двойные кавычки:

"Sammy says, "Hello!""

В этом примере закрывающая двойная кавычка перед Hello завершает строку, а двойная кавычка после Hello! создает новую строку, для которой нет соответствующей закрывающей кавычки, поэтому Ruby выдаст ошибку.

Чтобы избежать этой проблемы, у вас есть несколько вариантов. Во-первых, вы можете использовать альтернативный синтаксис для создания строк: если вам нужно использовать двойные кавычки в строке, используйте одинарные кавычки для определения строки и наоборот. Вы также можете экранировать кавычки или использовать другой синтаксис Ruby для определения строк. Давайте рассмотрим каждый подход.

Вариант 1: Использование альтернативного синтаксиса строки

Самый простой способ обойти эти проблемы – заключить вашу строку в одинарные кавычки, когда в вашей строке нужно использовать двойные кавычки, и заключить вашу строку в двойные кавычки, когда вашей строке нужно использовать одинарные кавычки.

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

'This isn't what I wanted.'

Определите ее двойными кавычками:

"This isn't what I wanted."

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

"Sammy says, "Hello!""

Используйте одинарные кавычки:

'Sammy says, "Hello!"'

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

"Sammy says, "I'm a happy shark!""

В этом примере закрывающая двойная кавычка перед I'm действительно сбивает все с толку. Это завершает первую строку, а затем Ruby сталкивается с апострофом в I'm, который начинает новую строку со значением m a happy shark!"". Но у этой новой строки нет соответствующих одинарных кавычек, чтобы ее завершить. И использование одинарных кавычек для заключения строки также вводит подобную проблему:

'Sammy says, "I'm a happy shark!"'

На этот раз апостроф в I'm завершает строку.

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

Вариант 2: Использование символов экранирования в строках

Символ обратной косой черты (\), часто называемый символом экранирования в строках, предотвратит интерпретацию Ruby следующего символа в строке буквально.

Вот наш проблемный строк, закодированный в двойных кавычках, с двойными кавычками внутри:

"Sammy says, "I'm a happy shark!""

Создайте новую программу Ruby с именем quoting.rb и добавьте этот код в файл:

quoting.rb
print "Sammy says, "I'm a happy shark!""

Запустите программу:

  1. ruby quoting.rb

И вы увидите такой вывод:

Output
quoting.rb:1: syntax error, unexpected tCONSTANT, expecting end-of-input print "Sammy says, "I'm a happy shark!"" ^

Чтобы исправить ошибку, используйте обратную косую черту перед внутренними двойными кавычками:

quoting.rb
print "Sammy says, \"I'm a happy shark!\""

Затем снова запустите программу, и вы увидите ожидаемый вывод:

Sammy says, "I'm a happy shark!"

Обратите внимание, что в этом примере вам не нужно экранировать апостроф, так как нет конфликта. Вам нужно экранировать только кавычки, которые сбивают с толку Ruby.

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

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

До сих пор вы использовали кавычки для определения границ ваших строк. Вы можете создавать строки в Ruby, используя также другие символы. Вы можете определить разделитель или символ, который вы хотели бы использовать для заключения вашей строки, указав его после знака процента, вот так:

%$Sammy says, "I'm a happy shark!"$

Этот синтаксис автоматически экранирует вложенные строки для вас. Фактическая строка выглядит так:

"Sammy says, \"I'm a happy shark!\""

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

Чтобы избежать этого, вы также можете использовать пары фигурных скобок, квадратных скобок или круглых скобок в качестве разделителей. Фигурные скобки наиболее распространены:

%{Sammy says, "I'm a happy shark!"}

Все эти формы поддерживают интерполяцию строк, если это необходимо.

droplets = 5
print %{Sammy says, "I just created #{droplets} droplets!"}

Вы также увидите использование %Q{} и %q{} для определения строк в программах на Ruby. Синтаксис %Q{} работает точно так же, как у двойных кавычек, что означает, что вам не нужно экранировать двойные кавычки, и вы сможете использовать интерполяцию строк:

droplets = 5
print %Q{Sammy says, "I just created #{droplets} droplets!"}

Синтаксис %q{} работает точно так же, как у одинарных кавычек:

%q{Sammy says, "I'm a happy shark!"}

Иногда вы можете увидеть синтаксис %q и %Q, используемый с круглыми скобками или квадратными скобками в некоторых программах вместо фигурных скобок.

Как видите, существует множество способов создания строк в Ruby. Какой бы метод вы ни выбрали, будьте последовательны в своем коде. Вы обнаружите, что методы %Q{} и %{} наиболее распространены.

Теперь, когда вы знаете, как обрабатывать специальные символы, давайте посмотрим, как обрабатывать длинные строки и символы новой строки.

Длинные строки и символы новой строки

Есть времена, когда вам может потребоваться вставить символ новой строки или возврата каретки в вашу строку. Вы можете использовать символы экранирования \n или \r для вставки новой строки в код:

output = "This is\na string\nwith newlines"
puts output

Эта программа выведет следующий результат:

Output
This is a string with newlines

Технически это работает для вывода нашего результата на нескольких строках. Однако написание очень длинной строки на одной строке быстро станет очень трудным для чтения и работы с ней. Есть несколько решений.

Во-первых, вы можете использовать оператор конкатенации, чтобы разбить строку на несколько строк:

output = "This is a\n" +
"longer string\n" +
"with newlines."
puts output

Это просто объединяет три строки вместе, подобно тому, что вы уже делали.

Вы также можете просто добавить переводы строк прямо в строку:

output = "This is a
longer string
with newlines"
puts output

Вы также можете использовать любые из альтернативных синтаксисов строк для создания многострочных строк:

output = %{This is a
longer string
with newlines}
puts output

В обоих этих примерах обратите внимание, что нам не нужны символы новой строки (\n). Этот подход сохраняет пробелы, включая отступы и переводы строк.

В результате вывод будет содержать переводы строк, а также весь ведущий отступ, как показано здесь:

Output
This is a longer string with newlines

Чтобы предотвратить это, удалите лишние пробелы из вашего кода:

output = %{This is a
longer string
with newlines
}

Вы также можете создавать многострочные строки, используя heredoc, или “здесь документ”, термин, используемый для многострочных литералов строк в программах. Вот как вы бы написали этот код:

output = <<-END
This is a
longer string
with newlines
END

Маркеры <<-END и END обозначают начало и конец heredoc.

В Ruby Heredocs также сохраняют пробельные символы, что означает, что если вы делаете отступ в коде внутри heredoc, то ведущий отступ также сохраняется. Так что этот код:

output = <<-END
This is a
longer string
with newlines
END

будет выводиться с двумя пробелами отступа.

Ruby 2.3 и выше предоставляют синтаксис “squiggly heredoc”, который автоматически удаляет ведущие пробелы. Замените дефис в определении heredoc на тильду, так что <<- становится <<~, вот так:

output = <<~END
This is a
longer string
with newlines
and the code is indented
but the output is not.
END

Это приводит к следующему выводу:

Output
This is a longer string with newlines and the code is indented but the output is not.

Это позволяет вам использовать heredocs и сохранять аккуратный отступ вашего кода.

Heredocs в Ruby также поддерживают интерполяцию строк.

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

Репликация строк

Могут быть моменты, когда вам нужно использовать Ruby для повторения строки символов несколько раз. Вы можете сделать это с помощью оператора *. Как и оператор +, оператор * имеет другое применение при использовании с числами, где он является оператором умножения. Когда используется с одной строкой и одним целым числом, * является оператором репликации строк, повторяя одну строку столько раз, сколько вы хотите, используя предоставленное вами целое число.

Для печати Sammy девять раз, вы бы использовали следующий код:

print "Sammy" * 9

Этот код выводит следующий результат:

Output
SammySammySammySammySammySammySammySammySammy

Вы можете использовать это для создания красивого ASCII-арт. Создайте файл с именем banner.rb и добавьте следующий код:

puts "=" * 15
puts "| Hello World |"
puts "=" * 15

Можете ли вы представить, что программа выведет до её запуска?

Она выводит следующее:

Output
=============== | Hello World | ===============

Это всего лишь маленький пример того, как можно заставить компьютер выполнять повторяющиеся задачи за вас.

Заключение

На этом уроке вы узнали, как работать с типом данных строки в языке программирования Ruby. Вы создавали новые строки, объединяли их с другими строками и обрабатывали переводы строк, кавычки и апострофы. Затем вы использовали интерполяцию строк, чтобы упростить смешивание строк и значений переменных, и узнали, как повторять строки.

Source:
https://www.digitalocean.com/community/tutorials/how-to-work-with-strings-in-ruby