Программирование на языке Ruby.

2.8. Разбиение строки на лексемы.

Метод split разбивает строку на части и возвращает массив лексем. Ему передаются два параметра: разделитель и максимальное число полей (целое).

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

S1 = "Была темная грозовая ночь.".

Words = s1.split      # ["Была", "темная", "грозовая", "ночь].

S2 = "яблоки, груши, персики".

List = s2.split(", ") # ["яблоки", "груши", "персики"].

S3 = "львы и тигры и медведи".

Zoo = s3.split(/ и /) # ["львы", "тигры", "медведи"].

Второй параметр ограничивает число возвращаемых полей, при этом действуют следующие правила:

1. Если параметр опущен, то пустые поля в конце отбрасываются.

2. Если параметр — положительное число, то будет возвращено не более указанного числа полей (если необходимо, весь «хвост» строки помещается в последнее поле). Пустые поля в конце сохраняются.

3. Если параметр — отрицательное число, то количество возвращаемых полей не ограничено, а пустые поля в конце сохраняются.

Ниже приведены примеры:

Str = "alpha,beta,gamma,,".

List1 = str.split(",")    # ["alpha","beta","gamma"].

List2 = str.split(",",2)  # ["alpha", "beta,gamma,,"].

List3 = str.split(",",4)  # ["alpha", "beta", "gamma", ","].

List4 = str.split(",",8)  # ["alpha", "beta", "gamma", "", "").

List5 = str.split(",",-1) # ["alpha", "beta", "gamma", "", ""].

Для сопоставления строки с регулярным выражением или с другой строкой служит метод scan:

Str = "I am a leaf on the wind...".

# Строка интерпретируется буквально, а не как регулярное выражение.

Arr = str.scan("а") # ["а","а","а"].

# При сопоставлении с регулярным выражением возвращаются все соответствия.

Arr = str.scan(/\w+/) # ["I", "am", "a", "leaf", "on", "the",

"wind"].

# Можно задать блок.

Str.scan(/\w+/) {|x| puts x }.

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

Require 'strscan'.

Str = "Смотри, как я парю!".

Ss = StringScanner.new(str).

Loop do.

 word = ss.scan(/\w+/) # Получать по одному слову.

 break if word.nil?

 puts word.

 sep = ss.scan(/\W+/)  # Получить следующий фрагмент,

                       # не являющийся словом.

 break if sep.nil?

End.