Home » Работа со строками в JavaScript
Работа со строками в JavaScript

Работа со строками в JavaScript

Строки в JavaScript — это не просто набор символов, а целый мир возможностей для автоматизации, обработки данных и создания мощных серверных решений. Если вы работаете с Node.js на сервере, настраиваете автоматические скрипты или обрабатываете логи, то правильная работа со строками может серьёзно упростить вашу жизнь. Сегодня разберём все тонкости: от базовых методов до хитрых трюков, которые сэкономят вам часы времени при написании серверных скриптов.

Основы работы со строками — как это работает под капотом

В JavaScript строки являются примитивным типом данных, но при этом ведут себя как объекты — у них есть свойства и методы. Это происходит благодаря автоматическому boxing’у, когда движок временно оборачивает примитив в объект String.

// Создание строк
let str1 = "Hello World";           // литерал (рекомендуется)
let str2 = new String("Hello");     // через конструктор (избегайте)
let str3 = `Template ${str1}`;      // шаблонная строка (ES6+)

// Основные свойства
console.log(str1.length);           // 11
console.log(str1[0]);               // "H"
console.log(str1.charAt(0));        // "H"

Важный момент: строки в JavaScript неизменяемы (immutable). Каждая операция создаёт новую строку, что нужно учитывать при работе с большими объёмами данных на сервере.

Практические методы для серверной разработки

Поиск и проверка содержимого

// Современные методы поиска (ES6+)
let logLine = "2024-01-15 ERROR: Database connection failed";

// Проверка наличия подстроки
console.log(logLine.includes("ERROR"));      // true
console.log(logLine.startsWith("2024"));     // true
console.log(logLine.endsWith("failed"));     // true

// Поиск позиции
console.log(logLine.indexOf("ERROR"));       // 11
console.log(logLine.lastIndexOf("a"));       // 31

// Регулярные выражения
console.log(logLine.search(/\d{4}-\d{2}-\d{2}/)); // 0
console.log(logLine.match(/\d{4}-\d{2}-\d{2}/));  // ["2024-01-15"]

Извлечение и обрезка

let config = "  server.port=3000; server.host=localhost  ";

// Удаление пробелов
let cleaned = config.trim();                    // убирает с краёв
let internal = config.replace(/\s+/g, ' ');    // заменяет множественные пробелы

// Извлечение подстрок
let port = config.substring(config.indexOf('=') + 1, config.indexOf(';'));
let slice1 = config.slice(2, 12);              // "server.por"
let slice2 = config.slice(-9, -2);             // "ocalhos"

// Разделение на части
let parts = cleaned.split(';');
let keyValue = parts[0].split('=');
console.log(keyValue);  // ["server.port", "3000"]

Шаблонные строки — мощь ES6+ для серверных скриптов

Шаблонные строки (template literals) — это не просто синтаксический сахар, а реальный инструмент для создания читаемого кода:

// Многострочные запросы SQL
const userId = 123;
const query = `
    SELECT u.name, u.email, p.title
    FROM users u
    LEFT JOIN posts p ON u.id = p.user_id
    WHERE u.id = ${userId}
    AND u.active = true
    ORDER BY p.created_at DESC
`;

// Генерация конфигурационных файлов
const generateNginxConfig = (domain, port) => `
server {
    listen 80;
    server_name ${domain};
    
    location / {
        proxy_pass http://localhost:${port};
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}`;

// Логирование с форматированием
const logError = (service, error, timestamp = new Date()) => 
    `[${timestamp.toISOString()}] ERROR in ${service}: ${error.message}`;

Продвинутые техники для автоматизации

Обработка логов и парсинг данных

// Парсинг Apache логов
const parseApacheLog = (logLine) => {
    const regex = /^(\S+) \S+ \S+ \[([^\]]+)\] "(\S+) (\S+) (\S+)" (\d+) (\d+|-) "([^"]*)" "([^"]*)"/;
    const match = logLine.match(regex);
    
    if (!match) return null;
    
    return {
        ip: match[1],
        timestamp: match[2],
        method: match[3],
        url: match[4],
        protocol: match[5],
        status: parseInt(match[6]),
        size: match[7] === '-' ? 0 : parseInt(match[7]),
        referer: match[8],
        userAgent: match[9]
    };
};

// Валидация и очистка пользовательского ввода
const sanitizeInput = (input) => {
    return input
        .trim()
        .replace(/[<>]/g, '') // удаляем опасные символы
        .substring(0, 1000);   // ограничиваем длину
};

// Генерация безопасных паролей
const generatePassword = (length = 12) => {
    const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*';
    return Array.from({length}, () => chars[Math.floor(Math.random() * chars.length)]).join('');
};

Работа с кодировками и специальными символами

// URL кодирование/декодирование
const url = 'https://example.com/search?q=hello world&lang=ru';
const encoded = encodeURIComponent(url);
const decoded = decodeURIComponent(encoded);

// Base64 кодирование (для API токенов)
const credentials = 'admin:password123';
const base64 = Buffer.from(credentials).toString('base64');
const authHeader = `Basic ${base64}`;

// Работа с Unicode
const emoji = '🚀';
console.log(emoji.length);                    // 2 (surrogate pair)
console.log([...emoji].length);              // 1 (правильный подсчёт)
console.log(emoji.codePointAt(0));          // 128640

Сравнение методов по производительности

Операция Быстрый способ Медленный способ Применение
Конкатенация Template literals Множественные += Формирование ответов API
Поиск подстроки includes() indexOf() !== -1 Фильтрация логов
Замена текста replaceAll() (ES2021) replace() с циклом Обработка конфигов
Проверка начала/конца startsWith(), endsWith() substring() + сравнение Роутинг запросов

Интеграция с серверными технологиями

Валидация данных с помощью регулярных выражений

// Валидаторы для серверных приложений
const validators = {
    email: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
    ipv4: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
    domain: /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
    port: /^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/
};

// Использование в Express middleware
const validateEmail = (req, res, next) => {
    const { email } = req.body;
    if (!validators.email.test(email)) {
        return res.status(400).json({ error: 'Invalid email format' });
    }
    next();
};

Обработка потоков данных

// Чтение и обработка больших файлов по частям
const fs = require('fs');
const readline = require('readline');

const processLogFile = async (filename) => {
    const fileStream = fs.createReadStream(filename);
    const rl = readline.createInterface({
        input: fileStream,
        crlfDelay: Infinity
    });

    const errors = [];
    
    for await (const line of rl) {
        if (line.includes('ERROR')) {
            const timestamp = line.match(/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/)?.[0];
            const message = line.substring(line.indexOf('ERROR') + 6);
            errors.push({ timestamp, message: message.trim() });
        }
    }
    
    return errors;
};

Инструменты и библиотеки для расширенной работы со строками

  • Lodash — мощная библиотека с полезными методами для строк
  • Validator.js — валидация и санитизация строк
  • String.js — расширенные методы для работы со строками
  • Moment.js / Day.js — парсинг и форматирование дат из строк
// Пример с validator.js
const validator = require('validator');

const isValidInput = (input) => {
    return validator.isLength(input, { min: 1, max: 100 }) &&
           validator.isAlphanumeric(input, 'en-US', { ignore: ' -_' }) &&
           !validator.contains(input, '