Глаза страшат, а руки делают

ЧАСТЬ ВТОРАЯ


19. Объект String
Свойство length, методы обработки строк

  • создание и использование объекта;
  • свойство length;
  • краткое описание ряда методов;
  • методы charAt(), slice();
  • методы lastIndexOf(), substring();
  • метод fromCharCode();
  • метод concat();
  • методы charCodeAt(), indexOf(), substr();
  • методы split(), toLowerCase(), toUpperCase().

Создание объекта String

Создать строковый объект можно с помощью конструктора new:

var имя_переменной = new String("некая_строка");

Однако гораздо чаще используется обычное присвоение:

var имя_переменной = "некая_строка";

В обоих случаях происходит почти одно и то же: интерпретатор создаёт экземпляр объекта String.

Почему «почти»?

Когда мы создаём строку вторым способом, то, говоря специальным языком, создаём не объект, а строковый литерал. Если мы вызываем для него метод, то JavaScript автоматически конвертирует его во временный объект String, вызывает этот метод, а затем уничтожает временный объект.

Если же мы создаём полноценный объект с помощью конструктора new, то мы сами же должны и управлять его поведением на всём протяжении скрипта. А поведение его может оказаться непредсказуемым.

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

Ну и совсем детский вопрос: почему во втором случае интерпретатор угадывает, что нужно создать именно объект String?

Потому что значение переменной было заключено в кавычки.

Значение объекта String (то, что я только что назвал строковым литералом) всегда должно быть в кавычках.

А может ли следующее выражение быть верным?

var имя_переменной = new String(некая_строка);

Может, если некая_строка — это имя переменной, на которую уже была назначена какая-то строка. Но само имя переменной не будет значением объекта String!

Примечание

Если воспринимать данное выражение буквально, то оно неверно, поскольку предполагаемое «имя переменной» записано русскими буквами, что запрещено в JavaScript.

Примечание

JavaScript чувствителен к регистру, поэтому всегда будьте внимательны при употреблении больших и маленьких букв в названиях свойств и методов!

Свойства объекта String

Объект String имеет три свойства:

  • constuctor
  • length
  • prototype

Свойства constuctor и prototype принадлежат объекту Object и наследуются всеми остальными объектами. О них мы поговорим, когда будем исследовать Object.

Свойство length

Как вы, наверно, уже догадались, это длина строки, то есть количество символов в строке.

var stroka = "Наука умеет много гитик";
var dlina = stroka.length
// Выводим количество символов:
document.write("Количество символов в переменной 'stroka': " + dlina);

Результат:

То есть 20 букв и 3 пробела.

Примечание для особо пытливых

В методе document.write() нашего примера выводится текст, составленный из строкового выражения в кавычках и переменной dlina с численным, то есть другим типом данных. Это возможно, так как JavaScript является слабо типизированным языком, то есть жёстко определять типы данных не требуется. В некоторых случаях (но не в этом) подобное небрежение может привести к нежелательным результатам, поэтому следует отдавать себе отчёт в том, какие типы данных мы используем.

Для подстраховки можно воспользоваться приведением, как в жёстко типизированных языках. Чтобы привести переменную dlina к строковому типу, можно воспользоваться методом toString(10), где (10) означает, что мы переводим в строку десятичное значение.

document.write("Количество символов в переменной 'stroka': " + dlina.toString(10));

Методы объекта String

Методов у этого объекта очень много. Чтобы не запутаться, уместно разбить их по категориям.

Методы обработки строк

Иногда их ещё называют стандартными методами. Этими методами можно программно изменять содержание строк, создавать на основе существующих строк новые строки, разбирать строки на массивы и, наоборот, создавать из массивов отдельные строковые объекты. Можно также выполнять в строке поиск заданного слова, части слова или отдельного символа (искомую часть строки обычно называют подстрокой [substring]), получить численный код символа или, наоборот, вывести символ по заданному численному коду.

Методы форматирования строк

Эти методы в основном дублируют форматирующие тэги HTML. Но благодаря их использованию в JavaScript можно создавать динамичные страницы, в которых форматирование может меняться либо по щелчку пользователя, либо в зависимости от разрешения экрана, типа браузера или каких-нибудь других условий (времени суток, например; да мало ли диковинного и забавного можно напридумывать).

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

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

Методы по полочкам

В этом разделе я даю краткие описания методов объекта String, которые будут рассмотрены в сегодняшнем уроке.

Метод charAt()

Возвращает символ, занимающий в строке указанную позицию.

Синтаксис

строка.charAt(индекс)

Аргумент

индекс — номер символа в строке. Индекс первого символа равен 0. Индекс последнего, соответственно, — строка.length-1.

Примечания

Если скобки оставить пустыми, метод возвратит нулевой (то есть первый) символ.

Если индекс превышает длину строки, возвращается значение NaN — свойство ядра, представляющее Not-A-Number/Не-Число (это свойство мы рассмотрим, когда будем учиться обрабатывать ошибки).

Примеры

"Бармалей".charAt(0)                     // возвращает "Б"
"Бармалей".charAt()                      // возвращает "Б"
"Бармалей".charAt(2)                     // возвращает "р"
"Бармалей".charAt("Бармалей".length-1)   // возвращает "й"
"Бармалей".charAt(32)                    // возвращает NaN

Метод charCodeAt()

Возвращает число, равное десятичному значению Unicode указанного символа.

Синтаксис

строка.charCodeAt(индекс)

Аргумент

индекс — номер символа в строке. Индекс первого символа равен 0. Индекс последнего, соответственно, — строка.length-1.

Примечание

Если индекс указывает несуществующую позицию, то возвращается NaN.

Примеры

"Строка".charCodeAt(0) /* Десятичный код русской буквы "С"
                          верхнего регистра: 1057 */
"Строка".charCodeAt(1).toString(16) /* 16-ричный код русской буквы "т"
                                       нижнего регистра: 442 */
"Строка".charCodeAt(8) // NaN (нет такой позиции)

Примечание

Во втором примере мы воспользовались также методом toString() объекта Object, который конвертирует любое число в строку значения этого числа в исчислении, заданном в аргументе (2, 8, 10 или 16). Именно этот метод использован в моих таблицах Unicode для отображения 16-ричных значений.

Метод fromCharCode()

Возвращает строку символов Unicode, числовые коды которой указаны в качестве параметров.

Это статический метод. В качестве строкового объекта используется базовый объект String собственной персоной (см. урок 18 об объектах и экземплярах).

Синтаксис

String.fromCharCode(номер1 [, номер2, ..., номерN])

Аргументы

номерN — числовой код символа (их может быть сколько угодно — в пределах разумного, конечно).

Примечания

IE4+, NN6+ поддерживают систему кодов Unicode, более старые версии — ISO-Latin 1.

Mozilla поддерживает Unicode.

Opera8+ поддерживает Unicode, причём корректнее, чем другие браузеры; о более старых версиях сведений не имею.

Примеры

String.fromCharCode(1040, 1085, 1076, 1088, 1077, 1081) // возвращает моё имя
String.fromCharCode(1078, 1086, 1087, 1072) /* возвращает
                                              не очень приличное слово*/

Метод indexOf()

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

Синтаксис

строка.indexOf(строка_поиска [, индекс])

Аргументы

crpoкa_noискa — подстрока, в которой надо произвести поиск.

индекс — индекс символа, с которого начинается поиск; если этот аргумент не введён, поиск производится от начала исходной строки.

Примеры

 "Абракадабра".indexOf("А")    // возвращает 0
//0123...
 "Абракадабра".indexOf("а")    // возвращает 3

Метод lastIndexOf()

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

Непонятно? Потерпите чуть-чуть.

Синтаксис

строка.lastIndexOf(строка_поиска [, индекс])

Аргументы

crpoкa_noискa — подстрока, в которой надо произвести поиск.

индекс — индекс символа, с которого начинается поиск; если этот аргумент не введён, поиск производится от конца исходной строки.

Примеры

 "Абракадабра".lastIndexOf("а")    // возвращает 10
//012345678910
 "Абракадабра".lastIndexOf("а", 9)    // возвращает 7

Метод slice()

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

Синтаксис

строка.slice(индекс1 [, индекс2])

Аргументы

индекс1 — индекс строки, с которого начинается подстрока. Индекс первого символа равен 0.

индекс2 — индекс строки, следующий за последним символом подстроки.

Примечания

Аргумент индекс2 не включается в подстроку. Чтобы из строки "пространство" извлечь подстроку "транс", последним параметром должен быть символ, идущий после «с»:

"Пространство".slice(4, 9)

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

Если параметр второго аргумента отрицателен, то отсчет конечного индекса производится от конца строки. При этом индекс2 соответствует последнему символу подстроки. Обратный отсчёт символов тоже с 0.

Примеры

"Бармалей".slice(0, 3)                  // возвращает "Бар"
"Бармалей".slice(3, 6)                  // возвращает "мал"
"Бармалей".slice(5)                     // возвращает "лей"
"Бармалей".slice(3, -2)                 // возвращает "мал"
"Бармалей".slice(5, 35)                 // возвращает "лей"

Метод substr()

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

Если длина не задана, то возвращается подстрока, начиная с данной позиции и до конца исходной строки.

Если длина отрицательна или равна нулю, то возвращается пустая строка.

Синтаксис

строка. substr(индекс [, длина])

Аргументы

индекс — начальная позиция подстроки в исходной строке.

длина — длина подстроки.

Примечание

Позиции символов строки нумеруются от нуля до строка.length-1. Если позиция больше или равна строка.length, то возвращается пустая строка. Если позиция отрицательна, то она трактуется как смещение от конца строки и заменяется на строка.length + индекс, то есть фактически даёт величину больше, чем строка.length

Внимание!

Если позиция отрицательна, то Internet Explorer ошибочно заменяет ее на 0, поэтому в целях совместимости этот вариант использовать не следует.

Пример

"Пространство".substr(4, 5)  // возвращает "транс"

Метод substring()

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

Синтаксис

строка.substring(индекс1, индекс2)

Аргументы

индекс1 — индекс строки, с которого начинается подстрока. Индекс первого символа равен 0.

индекс2 — индекс строки, следующий за последним символом подстроки.

Примечания

Порядок индексов не важен: наименьший из них считается начальным..

Больший параметр не включается в подстроку.

Если второй параметр больше длины исходной строки, то возвращается подстрока с начальной позицией индекс1 до конца строки.

Отличия от slice()

Оба индекса обязательны.

Не используется отрицательное значение индекса.

Начало и конец подстроки зависят не от порядка индексов, а от сравнения их величин.

Может быть, этого описания вам хватит. Попробуйте перейти сразу к домашним заданиям. Если выполнение заданий вас затруднит, читайте весь урок, в котором эти методы «разжёваны».

Методы обработки строк

Задача 1. Из полного адреса web-документа вычленяем имя файла

Первый вариант: используем методы charAt(), slice().

Допустим, у нас есть следующий адрес:

http://froland2.narod.ru/objects/string.html

Нам надо извлечь из него имя файла: string.html.

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

Слэш будем искать методом charAt().

Метод charAt()

Возвращает символ, занимающий в строке указанную позицию.

Синтаксис

строка.charAt(индекс)

Аргумент

индекс — номер символа в строке. Индекс первого символа равен 0. Индекс последнего, соответственно, — строка.length-1.

Примечания

Если скобки оставить пустыми, метод возвратит нулевой (то есть первый) символ.

Если индекс превышает длину строки, возвращается значение NaN — свойство ядра, представляющее Not-A-Number/Не-Число (это свойство мы рассмотрим, когда будем учиться обрабатывать ошибки).

Примеры

"Бармалей".charAt(0)                     // возвращает "Б"
"Бармалей".charAt()                      // возвращает "Б"
"Бармалей".charAt(2)                     // возвращает "р"
"Бармалей".charAt("Бармалей".length-1)   // возвращает "й"
"Бармалей".charAt(32)                    // возвращает NaN

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

Чтобы найти нужный индекс, надо перебрать символы циклом. Начнём строить код. Сначала сделаем упрощённый вариант для нашей заданной строки. Объявим переменные.

var str = "http://froland2.narod.ru/objects/string.html"
var endStr = str.length; // длина исходной строки
var symbol;              // переменная для поиска слэша
var str2;                // переменная для строки, которую мы хотим получить
var i;                   // счётчик цикла

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

for (i=endStr-1; i>=0; i--)
{
symbol = str.charAt(i);
    if (symbol=="/")
    . . . . . . . . . . . .

Итак, если переменная захватила слэш, то...

...то нам уже хватает данных, чтобы составить обрезанную подстроку. А для этого нам пригодится метод slice().

Метод slice()

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

Синтаксис

строка.slice(индекс1 [, индекс2])

Аргументы

индекс1 — индекс строки, с которого начинается подстрока. Индекс первого символа равен 0.

индекс2 — индекс строки, следующий за последним символом подстроки.

Примечания

Аргумент индекс2 не включается в подстроку. Чтобы из строки "пространство" извлечь подстроку "транс", последним параметром должен быть символ, идущий после «с»:

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

Если второй параметр отрицателен, то отсчет конечного индекса производится от конца строки. При этом индекс2 соответствует последнему символу подстроки. Обратный отсчёт символов тоже с 0.

Примеры

"Бармалей".slice(0, 3)                  // возвращает "Бар"
"Бармалей".slice(3, 6)                  // возвращает "мал"
"Бармалей".slice(5)                     // возвращает "лей"
"Бармалей".slice(3, -2)                 // возвращает "мал"
"Бармалей".slice(5, 35)                 // возвращает "лей"

Теперь можно вернуться к нашей задаче.

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

for (i=endStr-1; i>=0; i--)
{
symbol = str.charAt(i);
    if (symbol=="/")
    {
    str2 = str.slice(i+1);
    document.write(str2);
    break;
    }
}

А зачем break?

В нашей исходной строке несколько слэшей. Если мы не поставим break, то JavaScript продолжит свои изыскания и выдаст

string.htmlobjects/string.htmlfroland2.narod.ru/objects/string.html/froland2.narod.ru/objects/
string.html

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

function slicePath(str) {
    var endStr = str.length;
    var symbol;
    var str2;
    var i;
    for (i=endStr-1; i>=0; i--)
    {
    symbol = str.charAt(i);
        if (symbol=="/")
        {
        str2 = str.slice(i+1);
        document.write(str2);
        break;
        }
    }
}

А теперь определим этой функцией имя файла страницы, на которой мы находимся.

<script type="text/javascript">
var myPath = self.location.href
slicePath(myPath)
</script>

Результат:

lastIndexOf(), substring().

Этот вариант проще, он делается безо всяких циклов и ветвлений. Это возможно благодаря методу lastIndexOf().

Метод lastIndexOf()

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

Непонятно? Потерпите чуть-чуть.

Синтаксис

строка.lastIndexOf(строка_поиска [, индекс])

Аргументы

crpoкa_noискa — подстрока, в которой надо произвести поиск.

индекс — индекс символа, с которого начинается поиск; если этот аргумент не введён, поиск производится от конца исходной строки.

Абракадабра? Давайте разберёмся наглядно. Возьмём эту «абракадабру» в качестве исходной строки и поищем в ней «а», благо этих «а» там много (первая не считается: она у меня в верхнем регистре, а мы ищем в нижнем).

Если индекс не введён, поиск начинается от самого конца, сразу натыкается на последнюю «а» и выдаёт результат.

А теперь поменяйте картинку и посмотрите, как метод будет работать с разными индексами.

Результат: 10

Демонстрация обрывается на индексе 3. А что будет, если мы запросим 2, 1 или 0?

В этих случаях результат будет -1 [минус один], то есть false: не найдено!

Надеюсь, теперь вы уяснили, как работает метод.

Примечание

Первая буква «А» написана в верхнем регистре, поэтому не входит в диапазон поиска. А как «обманывать» регистрово-чувствительный JavaScript, мы тоже узнаем, но попозже.

Вернёмся к нашей задаче.

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

symbol = str.lastIndexOf("/");

А для формирования подстроки воспользуемся методом substring().

А почему не slice()? Да только потому, что мы его уже знаем. А так у меня есть повод подсунуть вам ещё один метод.

Метод substring()

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

Синтаксис

строка.substring(индекс1, индекс2)

Аргументы

индекс1 — индекс строки, с которого начинается подстрока. Индекс первого символа равен 0.

индекс2 — индекс строки, следующий за последним символом подстроки.

Примечания

Порядок индексов не важен: наименьший из них считается начальным..

Больший параметр не включается в подстроку.

Если второй параметр больше длины исходной строки, то возвращается подстрока с начальной позицией индекс1 до конца строки.

Отличия от slice()

Оба индекса обязательны.

Не используется отрицательное значение индекса.

Начало и конец подстроки зависят не от порядка индексов, а от сравнения их величин.

Наша искомая подстрока будет выглядеть следующим образом:

str2 = str.substring(symbol+1, str.length);

Теперь укатаем это в функцию:

function slicePath2(str) {
    var symbol;
    var str2;
    symbol = str.lastIndexOf("/");
    str2 = str.substring(symbol+1, str.length);
    document.write(str2);
}

Результат:

Задача 2. Создаём таблицу символов Unicode

Используемый метод: fromCharCode().

Иногда при вводе иностранных текстов или специальных значков требуется использовать закодированные символы Unicode.

Например:

для отображения символа ó нужно ввести в HTML-код &#243;

для отображения символа Æ нужно ввести в HTML-код &#198;

Числовое значение конструкции &#номер; и есть код символа Unicode.

Символов в Unicode несколько тысяч, запомнить их нереально. Но даже и сотню-другую запоминать не надо, можно воспользоваться таблицей. А где её взять? Сделать! Вот этим мы сейчас и займёмся.

Вот кусочек такой таблицы:

Вспомним, как в 6-м уроке мы создавали таблицу умножения циклом for. Сейчас нам потребуется нечто подобное.

Давайте сначала сделаем болванку HTML для 1 ряда таблицы Unicode. Столбцов в ряду сделаем 20 (это можно проделать в уме или на бумаге, я просто демонстрирую для наглядности).

<table>
<tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
    <td>4</td>
    <td>5</td>
    <td>6</td>
    <td>7</td>
    <td>8</td>
    <td>9</td>
    <td>10</td>
    <td>11</td>
    <td>12</td>
    <td>13</td>
    <td>14</td>
    <td>15</td>
    <td>16</td>
    <td>17</td>
    <td>18</td>
    <td>19</td>
    <td>20</td>
</tr>
<tr>
    <td>[код символа 1]</td>
    <td>[код символа 2]</td>
    <td>[код символа 3]</td>
    <td>[код символа 4]</td>
    <td>[код символа 5]</td>
    <td>[код символа 6]</td>
    <td>[код символа 7]</td>
    <td>[код символа 8]</td>
    <td>[код символа 9]</td>
    <td>[код символа 10]</td>
    <td>[код символа 11]</td>
    <td>[код символа 12]</td>
    <td>[код символа 13]</td>
    <td>[код символа 14]</td>
    <td>[код символа 15]</td>
    <td>[код символа 16]</td>
    <td>[код символа 17]</td>
    <td>[код символа 18]</td>
    <td>[код символа 19]</td>
    <td>[код символа 20]</td>
</tr>
<tr>
    <td>
        и.т.д., и т.д., и т.д.
    </td>
</tr>
</table>

Для вывода самих символов воспользуемся методом fromCharCode().

Метод fromCharCode()

Возвращает строку символов Unicode, числовые коды которой указаны в качестве аргументов.

Это статический метод. В качестве строкового объекта используется базовый объект String собственной персоной (см. урок 18 об объектах и экземплярах).

Синтаксис

String.fromCharCode(номер1 [, номер2, ..., номерN])

Аргументы

номерN — числовой код символа.

Примечания

IE4+, NN6+ поддерживают систему кодов Unicode, более старые версии — ISO-Latin 1.

Mozilla поддерживает Unicode.

Opera8+ поддерживает Unicode, причём корректнее, чем другие браузеры; о более старых версиях сведений не имею.

Примеры

String.fromCharCode(1040, 1085, 1076, 1088, 1077, 1081) // возвращает моё имя
String.fromCharCode(1078, 1086, 1087, 1072) /* возвращает
                                              не очень приличное слово*/

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

Не будем делать таблицу на весь Unicode, в котором встречаются символы с номерами больше 20000. Для начала ограничимся первыми 580. Почему 580? Первые 563 символа содержат практически исчерпывающий набор расширенной латиницы. Дальше наступает небольшой перерыв до 592-го символа, после чего появляются экзотические дополнительные символы, многие из которых дублируют символы предыдущего набора. А так как мы задали таблицу в 20 столбцов, то на 20 в этом пустом промежутке делится как раз 580.

Рядов у нас получается 58 (580:20=29, 29 — для номеров и 29 — для символов). Но поскольку каждые 2 ряда взаимосвязаны данными (фактически одни и те же данные, только в разных представлениях), по одному счётчику мы пустим 2 ряда. То есть шагов для счётчика рядов будет 29 (от 0 до 28). А 20 шагов счётчика столбцов сделаем от 1 до 20.

(Если вы не поняли и половины вышеизложенного — не беда. Сейчас начнём делать — и всё встанет на свои места.)

Объявим переменные счётчиков.

var i, j; // i - для рядов (<tr>), j - для столбцов (<td>)

Формируем остов таблицы:

document.write("<table width=\"600\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\" align=\"center\">")
for (i = 0; i <= 28; i++)
{
document.write("<tr>");  // для номеров
    . . .
    . . .
    . . .
document.write("</tr>")
document.write("<tr>");  // для символов
    . . .
    . . .
    . . .
document.write("</tr>")
}
document.write("</table>")

Туда, где сейчас стоят точки, нужно вставить циклы для столбцов. В них же будет и формула для вывода содержания. Давайте подумаем, как сделать, чтобы ячейки заполнились подряд номерами от 1 до 580.

Если j у нас от 1 до 20, то с первой парой рядов понятно: просто выводим j (хотя, как сейчас выяснится, и не совсем просто).

Во второй паре рядов нам нужно к каждому номеру прибавить 20, в третьей — 40 (то есть 2×20), в четвёртойй — 60 (то есть 3×20) и т.д.

Обратимся к уже определённой нами переменной i.

В первой паре рядов она равна 0, во второй — 1, в третьей — 2...

Смотрите!

20*i для первой пары рядов будет 0, для второй — 20, для третьей — 40...

Улавливаете?

Формула 20*i+j и даёт нам нужную последовательность. Кстати, понятно, почему i нужно задать от нуля?

Для ряда с номерами:

for (j = 1; j <= 20; j++)
{
document.write(<td width=\"5%\" align=\"center\">")
document.write(20*i+j)
document.write("</td>")
}

Для ряда с символами:

for (j = 1; j <= 20; j++)
{
document.write(<td width=\"5%\" align=\"center\">")
document.write(String.fromCharCode(20*i+j))
document.write("</td>")
}

Осталось вставить это в общий код:

document.write("<table width=\"600\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\" align=\"center\">")
for (i = 0; i <= 28; i++)
{
document.write("<tr>");  // для номеров
    for (j = 1; j <= 20; j++)
    {
    document.write(<td width=\"5%\" align=\"center\">")
    document.write(20*i+j)
    document.write("</td>")
    }
document.write("</tr>")
document.write("<tr>");  // для символов
    for (j = 1; j <= 20; j++)
    {
    document.write(<td width=\"5%\" align=\"center\">")
    document.write(String.fromCharCode(20*i+j))
    document.write("</td>")
    }
document.write("</tr>")
}
document.write("</table>")

А посмотреть результат можно здесь.

Примечания

Для отображения максимального количества символов Unicode лучше всего использовать шрифты @Arial Unicode MS и @MS Mincho, имеющиеся в стандартном наборе Windows XP. Их можно ввести в наши <td> стилем CSS font-family.

Символы 127–159 и 536–563 даже с этими шрифтами показывает только Opera. Остальные браузеры дают пустые квадраты.

Time-Out

Нет, это не название метода! Просто мы слегка передохнём и подведём первые итоги.

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

charAt()

charCodeAt()

fromCharCode()

concat()

indexOf()

lastIndexOf()

localeCompare()

match()

replace()

search()

slice()

split()

substr()

substring()

toLocaleLowerCase()

toLocaleUpperCase()

toLowerCase()

toUpperCase()

Бледно-синим обозначены «кривые» методы, которые зависят от локальных настроек, по-разному работают в разных браузерах, и вообще — лучше с ними дела не иметь. Но знать об их существовании, наверно, всё-таки, надо.

Зелёным обозначены методы, которые требуют использования регулярных выражений. Регулярные выражения, этот своего рода «язык в языке», мы рассмотрим в связи с их «контейнером» — объектом RegExp. Это будет уже в четвёртой части наших уроков. Но эти методы могут работать и с простыми строками, и мы их тоже рассмотрим (коснувшись регулярных выражений лишь там, где это неизбежно).

Задача 3. Казнить  нельзя, помиловать

Используемый метод: concat().

В программировании есть понятие конкатенация, происходящее от английского слова concatenation — «объединение», «сочленение», «сцепление». Это понятие применяется к сложению нескольких строк в одну или нескольких массивов в один. Для этого можно использовать метод concat(), работающий как с объектами String, так и с объектами Array.

Более полезен и интересен этот метод в работе с массивами. Со строками же вместо этого можно использовать простые выражения с плюсиками:

document.write("мама " + "мыла" + " раму")

Пробелы должны быть в самих строках. Или, можно для ясности показать их отдельно:

document.write("мама" + " " + "мыла" + " " + "раму")

Но раз уж этот метод существует и для строк, то мы рассмотрим его и здесь.

Метод concat()

Ввозвращает новую строку, являющуюся конкатенацией исходной строки и аргументов метода.

Синтаксис

объект.concat(строка1 [, строка2, ..., строкаN])

Аргументы

объект — исходная строка.

строкаN — N-ная строка, приклеенная к исходной строке.

Пример

var word1 = "Казнить"
var word2 = "нельзя"
var word3 = "помиловать."
var comma = ", "
var space = " "
document.write(word1.concat(comma, word2, space, word3) + "<br>")
document.write(word1.concat(space, word2, comma, word3))

Результат:

Понятно? Устанавливаем запятую и пробел в разные места.

А вот примерчик чуть похитрее. В нём используются два небольших строковых массива, но сам метод применён к объектам String.

Вот маленькое стихотворение В. Хлебникова:

В каждой строке есть общая подстрока:

"Когда умирают "

Прослеживаются два синхронных строковых массива:

["кони", "травы", "солнца", "люди"]

["дышат,", "сохнут,", "они гаснут,", "поют песни."]

А также соединяющее их тире с пробелами (воспользуемчя спецсимволом):

" &mdash; "

Формируем переменные:

/* Счётчик для цикла: */
var i
/* Общие подстроки: */
var a = "Когда умирают "
var b = " &mdash; "
/* Массивы: */
arr1 = ["кони", "травы", "солнца", "люди"]
arr2 = ["дышат,<br>", "сохнут,<br>", "они гаснут,<br>", "поют песни."]
/* Во втором массиве сразу пометим концы строк тэгом <br> */

Теперь строим скрипт, последовательно выводящий нужный текст:

for (i=0; i<4; i++)
{document.write(a.concat(arr1[i], b, arr2[i]))}

Подобная игрушка может оказаться удобной для создания множества копий какого-нибудь фирменного бланка с разными данными.

Если вам интересно, каким образом мигает запятая в заголовке, то сегодня я вас разочарую. Это делается методом setInterval(), относящимся к объекту Date. О нём — попозже.

Дополним комплект

Раз уж мы познакомились с методами charAt() и fromCharCode(), то дополним эту группу методом charCodeAt(). В компанию к методу lastIndexOf() добавим родственный ему indexOf(). А в связи с substring() упомянем и его «обрубок» — substr().

Метод charCodeAt()

Если известный нам метод charAt() возвращает символ, занимающий в строке указанную позицию, то метод charCodeAt() возвращает число, равное десятичному значению Unicode этого символа.

Синтаксис

строка.charCodeAt(индекс)

Аргумент

индекс — номер символа в строке. Индекс первого символа равен 0. Индекс последнего, соответственно, — строка.length-1.

Примечание

Если индекс указывает несуществующую позицию, то возвращается NaN.

Примеры

"Строка".charCodeAt(0) /* Десятичный код русской буквы "С"
                          верхнего регистра: 1057 */
"Строка".charCodeAt(1).toString(16) /* 16-ричный код русской буквы "т"
                                       нижнего регистра: 442 */
"Строка".charCodeAt(8) // NaN (нет такой позиции)

Примечание

Во втором примере мы воспользовались также методом toString() объекта Object, который конвертирует любое число в строку значения этого числа в исчислении, заданном в аргументе (2, 8, 10 или 16). Именно этот метод использован в моих таблицах Unicode для отображения 16-ричных значений.

Метод indexOf()

Отличается от метода lastIndexOf() только тем, что производит поиск строки, указанной аргументом, начиная с начала исходной строки, а возвращаемый индекс точно так же отсчитывается от ее начала, то есть от 0.

Синтаксис

строка.indexOf(строка_поиска [, индекс])

Аргументы

crpoкa_noискa — подстрока, в которой надо произвести поиск.

индекс — индекс символа, с которого начинается поиск; если этот аргумент не введён, поиск производится от начала исходной строки.

Примеры

 "Абракадабра".indexOf("А")    // возвращает 0
//0123...
 "Абракадабра".indexOf("а")    // возвращает 3

Метод match()

Этот метод ищет подстроку по заданному образцу. Образцами могут быть регулярные выражения, и полностью мы рассмотрим возможности метода, когда доберёмся до них. Но образцами могут быть и простые строки.

Синтаксис

строка.match(образец)

Аргумент

образец — подстрока, которую надо найти в строке: регулярное или строковое выражение.

Возвращает строку образца, если он найден. Если образец не найден, возвращает null.

Примечание

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

Пример

var myStr1 = "Пространство"
var myStr2 = myStr1.match("транс")
var myStr3 = myStr1.match("Транс")
var myStr4 = myStr1.match("транспорт")
var myStr5 = "Соответствий нет."

if (myStr2 != null)
document.write("<p>" + myStr2 + "</p>")
else
document.write("<p>" + myStr5 + "</p>")
if (myStr3 != null)
document.write("<p>" + myStr3 + "</p>")
else
document.write("<p>" + myStr5 + "</p>")
if (myStr4 != null)
document.write("<p>" + myStr4 + "</p>")
else
document.write("<p>" + myStr5 + "</p>")

Результат

(Как видите, регистр учитывается.)

Этот метод наиболее эффективен при работе с регулярными выражениями, но и с простыми строками может быть полезен. Например, он удобен при создании «заглушек» на пункты меню.

Предположим, есть массив links[] с именами файлов страниц.

for (i=0; i<links.length; i++)
{
    if (self.location.href.match(links[i]) == links[i])
    // выводим пункт меню без ссылки
    else
    // выводим пункт меню со ссылкой
}

Этот способ лучше рассмотренных в предыдущих методах.

Если на странице есть ссылка-якорь (lesson2.html#objects) или QUERY_STRING (lesson2.html?page3), то меню, сделанное функцией slicePath(), будет сбоить.

Метод replace()

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

Синтаксис

строка.replace(образец, замена[или функция])

Аргументы

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

замена — подстрока для замены.

функция — функция, возвращающаа подстроку для замены (может использоваться, если в первом аргументе регулярное выражение).

Примеры

var Str_1 = "Когда умирают кони — дышат,<br>";
var Str_2 = Str_1.replace("кони","травы").replace("дышат","сохнут");
var Str_3 = Str_1.replace("кони","солнца").replace("дышат","они гаснут");
var Str_4 = Str_1.replace("кони","люди").replace("дышат,<br>","поют песни.");
document.write(Str_1 + Str_2 +  Str_3 + Str_4);

Результат

var myName = "Андрей Андреевич Фролов";
document.write(myName.replace("Андреевич", ""));

Результат

В замене могут использоваться специальные сочетания символов:

$$

Вставляет знак $

$&

Вставляет совпавшую подстроку

$`

Вставляет часть строки, которая предшествует совпавшей подстроке

$'

Вставляет часть строки, которая следует за совпавшей подстрокой

$n или $nn

(n/nn — цифры)

Вставляет n-ю скобку в совпадении (если образец — регулярное выражение)

В выражении /(мама) (мыла) (раму)/ (мама) — $1, (мыла) — $2, (раму) — $3.


Примечание

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

Это мы будем исследовать позже, но для удовлетворения любопытства и «шапочного знакомства» с регулярными выражениями кое-что самое элементарное покажу.

Заменяем последнюю часть строки на предшествующую часть:

document.write(myName.replace("Фролов", "$`"))

Результат

Результат в IE

Андрей Андреевич $`

А сейчас мы запишем тот же самый первый аргумент в синтаксисе регулярного выражения:

document.write(myName.replace(/Фролов/, "$`"))

Результат во всех браузерах

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

document.write(myName.replace(/(Андрей) (Андреевич) (Фролов)/, "$3, $1 $2"))

Результат

А в этих головоломках попробуйте разобраться сами:

document.write(myName.replace(/Андрей ((Андреев)ич) (Фрол)ов/, "$3 $1 $2"))
document.write(myName.replace(/(А(н)др)ей (А)н(д)р(ее(в))(ич) (Фр(о)лов)/, "$1$9$2 $8$7 $3$6$4$5"))

Результаты

Подсказка: скобки вкладываются друг в друга, а не перекрещиваются.

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

Метод search()

Сопоставляет регулярное выражение, заданное в шаблоне, с искомой строкой. Возвращает позицию первого вхождения шаблона в строку (нумерация с 0, если вхождений нет, возвращает -1).

Синтаксис

строка.search(шаблон)

Аргумент

шаблон — любое регулярное выражение

Опция глобального поиска в шаблоне игнорируеися.

Примеры

(Последний раз потреплем моё несчастное имя.)

document.write("Первое вхождение символа «н»: " + myName.search(/н/) + "<br>");
document.write("Первое вхождение подстроки «ндр»: " + myName.search(/ндр/) + "<br>");
document.write("Первое вхождение символа «в»: " + myName.search(/в/) + "<br>");
document.write("Первое вхождение символа «а» (с учётом регистра): " + myName.search(/а/) + "<br>");
document.write("Первое вхождение символа «а» (без учёта регистра): " + myName.search(/а/i));

Результаты

Пояснение: в последнем примере после регулярного выражения стоит модификатор «i» (ignore), предписывающий игнорировать регистр.

Метод substr()

В методах slice() и substring мы находили подстроку по заданным координатам начала и конца

Метод substr() возвращает подстроку, начинающуюся с данной позиции и содержащую длину символов. То есть в качестве аргументов мы имеем начальную координату и длину подстроки.

Если длина не задана, то возвращается подстрока, начиная с данной позиции и до конца исходной строки.

Если длина отрицательна или равна нулю, то возвращается пустая строка.

Синтаксис

строка.substr(индекс [, длина])

Аргументы

индекс — начальная позиция подстроки в исходной строке.

длина — длина подстроки.

Примечание

Позиции символов строки нумеруются от нуля до строка.length-1. Если позиция больше или равна строка.length, то возвращается пустая строка. Если позиция отрицательна, то она трактуется как смещение от конца строки и заменяется на строка.length + индекс, то есть фактически даёт величину больше, чем строка.length

Внимание!

Если позиция отрицательна, то Internet Explorer ошибочно заменяет ее на 0, поэтому в целях совместимости этот вариант использовать не следует.

Пример

"Пространство".substr(4, 5)  // возвращает "транс"

Методы split(), toLowerCase(), toUpperCase()

Метод split()

Разбивает строку на массив строк.

Синтаксис

строка.split(разделитель [, ограничитель])

Аргументы

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

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

Примечания

Если разделитель — пустая строка, то возвращается массив символов строки.

Если разделитель не указан, то внешне ничего не меняется: возвращается просто исходная строка. Но она превращается в массив из одного элемента. Это можно проверить через запрос свойства length: оно всегда будет равно 1 (а у строки это свойство было бы равно количеству символов).

Примеры

"Абракадабра".split("а")    // возвращает "Абр,к,д,бр,"
"Абракадабра".split("б")    // возвращает "А,ракада,ра"
"Абракадабра".split("ра")   // возвращает "Аб,кадаб,"
"Абракадабра".split("")     // возвращает "А,б,р,а,к,а,д,а,б,р,а"
"Абракадабра".split()       // возвращает "Абракадабра"

"Мама мыла раму".split(" ")    // возвращает "Мама,мыла,раму"
"Мама мыла раму".split(" ", 2// возвращает "Мама,мыла"

Обратите внимание

Если вывести результаты методом document.write(), то первый и третий массивы строк получатся с запятой на конце, а второй — без. Это получается, потому что в первом и третьем массивах разделитель попадает на последний символ исходной строки, и после него создаётся пустой элемент массива. Можно проверить:

document.write("Абракадабра".split("а").length)    // возвращает 5 (а не 4)
document.write("Абракадабра".split("б").length)    // возвращает 3
document.write("Абракадабра".split("ра").length)   // возвращает 3 (а не 2)
document.write("Абракадабра".split("").length)     // возвращает 11
document.write("Абракадабра".split().length)       // возвращает 1

Методы toLowerCase() и toUpperCase()

Приводят все символы строки к нижнему или верхнему регистру.

Синтаксис

строка.toLowerCase()
строка.toUpperCase()

Примеры

"Абракадабра".toLowerCase()    // возвращает "абракадабра"
"Абракадабра".toUpperCase()    // возвращает "АБРАКАДАБРА"

Примечание

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

Домашние задания

1. С помощью любых из разобранных методов создайте функции для выведения частей адресов электронной почты до и после «собаки».

2. Соорудите таблицу для русских символов (без «ё»)

Их всего 64: 32 больших и 32 маленьких. Удобно делать таблицу из 16 столбцов. Параметр 1 символа — 1040. Далее по порядку.

Здесь переменную i нужно определить от 65 до 68, а j — не от 1 до 16, а от 0 до 15. Догадайтесь, почему.

Формула fromCharCode... ну так и быть, подскажу.

Результат можно посмотреть здесь.

3. Сделайте скрипт метода concat() на тему:

Подумайте, как можно программно заменить «будет» на «буду». Если не додумаетесь, откройте подсказку.

4. Методами slice(), substring() и substr() выведите слово «приз» из слова «беспризорник».

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

Использовать простое сложение строк сегодня запрещаю!


Итак, мы узнали:

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


К следующему уроку >>


 012831