DA
Tüm yazılara dön
Metin Araçları: Profesyonel İçerik Düzenleme ve Manipülasyon Rehberi

Metin Araçları: Profesyonel İçerik Düzenleme ve Manipülasyon Rehberi

metin araçlarıtext processingencodingstring manipulationcontent editingdeveloper tools

Metin Araçları: Profesyonel İçerik Düzenleme ve Manipülasyon Rehberi

Modern dijital dünyada metin işleme, her profesyonelin ihtiyaç duyduğu temel becerilerden biridir. Yazarlar, geliştiriciler, editörler ve içerik üreticileri günlük olarak metin dönüştürme, formatlama ve optimizasyon işlemleri gerçekleştirir. Bu kapsamlı rehberde, profesyonel metin işleme araçları, teknikleri ve en iyi uygulamaları detaylı olarak inceleyeceğiz.

Metin İşleme Temelleri

Karakter Kodlaması ve Encoding

Unicode ve UTF-8

Modern metin işleme Unicode standardına dayanır:

ASCII (American Standard Code for Information Interchange):

  • 128 karakter (0-127)
  • Sadece İngilizce karakterler
  • Eski sistemlerde kullanım

UTF-8 (Unicode Transformation Format):

  • Variable-length encoding
  • ASCII ile geriye dönük uyumluluk
  • Web standardı
  • Çok dilli destek
// Karakter encoding örnekleri
const text = "Merhaba Dünya! 🌍";

// UTF-8 bytes
const utf8Bytes = new TextEncoder().encode(text);
console.log(utf8Bytes); // Uint8Array

// Base64 encoding
const base64 = btoa(unescape(encodeURIComponent(text)));
console.log(base64); // TWVyaGFiYSBEdW55YSEg8J+MjQ==

// URL encoding
const urlEncoded = encodeURIComponent(text);
console.log(urlEncoded); // Merhaba%20D%C3%BCnya!%20%F0%9F%8C%8D

Metin Normalizasyonu

Case Transformations

// Büyük/küçük harf dönüşümleri
const text = "Merhaba DÜNYA";

const transformations = {
  lower: text.toLowerCase(), // "merhaba dünya"
  upper: text.toUpperCase(), // "MERHABA DÜNYA"
  title: toTitleCase(text), // "Merhaba Dünya"
  camel: toCamelCase(text), // "merhabaDunya"
  pascal: toPascalCase(text), // "MerhabaDunya"
  snake: toSnakeCase(text), // "merhaba_dunya"
  kebab: toKebabCase(text), // "merhaba-dunya"
};

Metin Araçları Koleksiyonumuz

📝 Metin Araçları

Profesyonel metin işleme için tasarlanmış kapsamlı araç seti:

Özellik 1: Karakter Dönüştürme

Case Transformation Araçları:

1. Büyük/Küçük Harf Dönüştürme

Girdi: "merhaba DÜNYA"
Çıktılar:
- Küçük harf: "merhaba dünya"
- Büyük harf: "MERHABA DÜNYA"
- Title Case: "Merhaba Dünya"
- Sentence case: "Merhaba dünya"

2. Programming Case Styles

Girdi: "user first name"
Çıktılar:
- camelCase: "userFirstName"
- PascalCase: "UserFirstName"
- snake_case: "user_first_name"
- kebab-case: "user-first-name"
- CONSTANT_CASE: "USER_FIRST_NAME"

Özellik 2: Metin Temizleme

Whitespace Management:

// Boşluk karakteri temizleme
function cleanWhitespace(text) {
  return text
    .replace(/\s+/g, " ") // Çoklu boşlukları tek boşluğa
    .replace(/^\s+|\s+$/g, "") // Başlangıç/bitiş boşlukları
    .replace(/\n\s*\n/g, "\n") // Çoklu satır sonlarını temizle
    .trim();
}

HTML Tag Removal:

// HTML etiketlerini temizleme
function stripHTMLTags(html) {
  return html
    .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "")
    .replace(/<[^>]*>/g, "")
    .replace(/&nbsp;/g, " ")
    .replace(/&amp;/g, "&")
    .replace(/&lt;/g, "<")
    .replace(/&gt;/g, ">");
}

Özellik 3: Encoding/Decoding

Base64 Operations:

// Base64 encode/decode
class Base64Tools {
  static encode(text) {
    try {
      return btoa(unescape(encodeURIComponent(text)));
    } catch (error) {
      throw new Error("Base64 encoding hatası: " + error.message);
    }
  }

  static decode(base64) {
    try {
      return decodeURIComponent(escape(atob(base64)));
    } catch (error) {
      throw new Error("Base64 decoding hatası: " + error.message);
    }
  }
}

URL Encoding:

// URL encoding/decoding
class URLTools {
  static encode(text) {
    return encodeURIComponent(text);
  }

  static decode(encodedText) {
    try {
      return decodeURIComponent(encodedText);
    } catch (error) {
      return encodedText; // Decode edilemezse orijinal döndür
    }
  }

  static encodeForQuery(params) {
    return Object.keys(params)
      .map(
        (key) => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
      )
      .join("&");
  }
}

Özellik 4: Hash Oluşturma

Crypto-JS Integration:

// Hash fonksiyonları
class HashTools {
  static async md5(text) {
    const msgBuffer = new TextEncoder().encode(text);
    const hashBuffer = await crypto.subtle.digest("MD5", msgBuffer);
    const hashArray = Array.from(new Uint8Array(hashBuffer));
    return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
  }

  static async sha256(text) {
    const msgBuffer = new TextEncoder().encode(text);
    const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
    const hashArray = Array.from(new Uint8Array(hashBuffer));
    return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
  }

  static simpleHash(text) {
    let hash = 0;
    for (let i = 0; i < text.length; i++) {
      const char = text.charCodeAt(i);
      hash = (hash << 5) - hash + char;
      hash = hash & hash; // 32-bit integer
    }
    return Math.abs(hash).toString(16);
  }
}

Özellik 5: İstatistik ve Analiz

Metin İstatistikleri:

class TextAnalytics {
  static analyze(text) {
    const cleanText = text.replace(/\s+/g, " ").trim();

    return {
      characters: text.length,
      charactersNoSpaces: text.replace(/\s/g, "").length,
      words: cleanText ? cleanText.split(" ").length : 0,
      sentences: text.split(/[.!?]+/).filter((s) => s.trim()).length,
      paragraphs: text.split(/\n\s*\n/).filter((p) => p.trim()).length,
      averageWordsPerSentence: this.calculateAverageWordsPerSentence(text),
      readingTime: this.calculateReadingTime(cleanText),
      mostFrequentWords: this.getMostFrequentWords(cleanText),
    };
  }

  static calculateReadingTime(text, wordsPerMinute = 200) {
    const wordCount = text.split(" ").filter((word) => word).length;
    const minutes = Math.ceil(wordCount / wordsPerMinute);
    return minutes;
  }

  static getMostFrequentWords(text, count = 10) {
    const words = text
      .toLowerCase()
      .replace(/[^\w\s]/g, "")
      .split(/\s+/)
      .filter((word) => word.length > 2);

    const frequency = {};
    words.forEach((word) => {
      frequency[word] = (frequency[word] || 0) + 1;
    });

    return Object.entries(frequency)
      .sort(([, a], [, b]) => b - a)
      .slice(0, count)
      .map(([word, freq]) => ({ word, frequency: freq }));
  }
}

Programlama Dilleri İçin Metin İşleme

JavaScript String Methods

Modern ES2021+ Features

// String manipulation modern yöntemler
class ModernStringTools {
  // Replaceall - tüm eşleşmeleri değiştir
  static replaceAll(text, search, replacement) {
    return text.replaceAll(search, replacement);
  }

  // Padding - sol/sağ dolgulama
  static padText(text, length, padChar = " ", direction = "start") {
    return direction === "start"
      ? text.padStart(length, padChar)
      : text.padEnd(length, padChar);
  }

  // Trimming variations
  static trimVariations(text) {
    return {
      trim: text.trim(), // Başlangıç ve bitiş
      trimStart: text.trimStart(), // Sadece başlangıç
      trimEnd: text.trimEnd(), // Sadece bitiş
    };
  }

  // Template literal ile formatting
  static formatTemplate(template, data) {
    return template.replace(/\${(\w+)}/g, (match, key) => {
      return data[key] !== undefined ? data[key] : match;
    });
  }
}

Regular Expressions (Regex)

Yaygın Regex Patterns

// Regex pattern koleksiyonu
const RegexPatterns = {
  email: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
  phone: /^(\+\d{1,3}[- ]?)?\d{10}$/,
  url: /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/,
  creditCard: /^\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}$/,
  ipAddress:
    /^(?:(?: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]?)$/,
  strongPassword:
    /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/,
  htmlTags: /<[^>]*>/g,
  whitespace: /\s+/g,
  digits: /\d+/g,
};

// Regex kullanım örnekleri
class RegexTools {
  static validateEmail(email) {
    return RegexPatterns.email.test(email);
  }

  static extractUrls(text) {
    return text.match(RegexPatterns.url) || [];
  }

  static cleanHTML(html) {
    return html.replace(RegexPatterns.htmlTags, "");
  }

  static normalizeWhitespace(text) {
    return text.replace(RegexPatterns.whitespace, " ").trim();
  }
}

İçerik Üretimi ve SEO Optimizasyonu

Keyword Density Analizi

class SEOTextAnalyzer {
  static calculateKeywordDensity(text, keyword) {
    const cleanText = text.toLowerCase().replace(/[^\w\s]/g, " ");
    const words = cleanText.split(/\s+/).filter((word) => word);
    const keywordLower = keyword.toLowerCase();

    const keywordCount = words.filter(
      (word) => word === keywordLower || word.includes(keywordLower)
    ).length;

    return {
      totalWords: words.length,
      keywordCount,
      density: ((keywordCount / words.length) * 100).toFixed(2),
      recommendation: this.getDensityRecommendation(
        keywordCount / words.length
      ),
    };
  }

  static getDensityRecommendation(density) {
    if (density < 0.01)
      return "Çok düşük - anahtar kelimeyi daha fazla kullanın";
    if (density > 0.03) return "Çok yüksek - anahtar kelime stuffing riski";
    return "Optimal - iyi denge";
  }

  static generateMetaDescription(text, maxLength = 160) {
    const sentences = text
      .split(/[.!?]+/)
      .map((s) => s.trim())
      .filter((s) => s);
    let metaDesc = "";

    for (const sentence of sentences) {
      if ((metaDesc + sentence).length <= maxLength) {
        metaDesc += (metaDesc ? " " : "") + sentence;
      } else {
        break;
      }
    }

    return metaDesc + (metaDesc.length < text.length ? "..." : "");
  }
}

Readability Analysis

class ReadabilityAnalyzer {
  // Flesch-Kincaid Reading Ease Score
  static calculateFleschScore(text) {
    const sentences = text.split(/[.!?]+/).filter((s) => s.trim()).length;
    const words = text.split(/\s+/).filter((w) => w).length;
    const syllables = this.countSyllables(text);

    const avgSentenceLength = words / sentences;
    const avgSyllablesPerWord = syllables / words;

    const score =
      206.835 - 1.015 * avgSentenceLength - 84.6 * avgSyllablesPerWord;

    return {
      score: Math.max(0, Math.min(100, score)),
      level: this.getReadingLevel(score),
      sentences,
      words,
      syllables,
      avgSentenceLength: avgSentenceLength.toFixed(1),
      avgSyllablesPerWord: avgSyllablesPerWord.toFixed(1),
    };
  }

  static countSyllables(text) {
    return (
      text
        .toLowerCase()
        .replace(/[^a-z]/g, "")
        .replace(/e$/, "")
        .replace(/[aeıioöuüy]{2,}/g, "a")
        .replace(/[aeıioöuüy]/g, "X")
        .replace(/[^X]/g, "").length || 1
    );
  }

  static getReadingLevel(score) {
    if (score >= 90) return "Çok kolay";
    if (score >= 80) return "Kolay";
    if (score >= 70) return "Oldukça kolay";
    if (score >= 60) return "Standart";
    if (score >= 50) return "Oldukça zor";
    if (score >= 30) return "Zor";
    return "Çok zor";
  }
}

CSV ve Structured Data İşleme

CSV Parser ve Generator

class CSVTools {
  static parseCSV(csvText, delimiter = ",", hasHeader = true) {
    const lines = csvText.trim().split("\n");
    const headers = hasHeader ? this.parseLine(lines[0], delimiter) : null;
    const dataLines = hasHeader ? lines.slice(1) : lines;

    const data = dataLines.map((line) => {
      const values = this.parseLine(line, delimiter);

      if (headers) {
        const obj = {};
        headers.forEach((header, index) => {
          obj[header] = values[index] || "";
        });
        return obj;
      }

      return values;
    });

    return { headers, data };
  }

  static generateCSV(data, headers = null) {
    if (!Array.isArray(data) || data.length === 0) {
      return "";
    }

    // Auto-detect headers from object keys
    if (!headers && typeof data[0] === "object") {
      headers = Object.keys(data[0]);
    }

    let csv = "";

    // Add headers
    if (headers) {
      csv += headers.map((header) => this.escapeField(header)).join(",") + "\n";
    }

    // Add data rows
    data.forEach((row) => {
      if (Array.isArray(row)) {
        csv += row.map((field) => this.escapeField(field)).join(",") + "\n";
      } else if (typeof row === "object") {
        const values = headers.map((header) => row[header] || "");
        csv += values.map((field) => this.escapeField(field)).join(",") + "\n";
      }
    });

    return csv;
  }

  static parseLine(line, delimiter) {
    const result = [];
    let current = "";
    let inQuotes = false;

    for (let i = 0; i < line.length; i++) {
      const char = line[i];
      const nextChar = line[i + 1];

      if (char === '"') {
        if (inQuotes && nextChar === '"') {
          current += '"';
          i++; // Skip next quote
        } else {
          inQuotes = !inQuotes;
        }
      } else if (char === delimiter && !inQuotes) {
        result.push(current);
        current = "";
      } else {
        current += char;
      }
    }

    result.push(current);
    return result;
  }

  static escapeField(field) {
    const stringField = String(field);
    const needsEscaping =
      stringField.includes(",") ||
      stringField.includes('"') ||
      stringField.includes("\n");

    if (needsEscaping) {
      return '"' + stringField.replace(/"/g, '""') + '"';
    }

    return stringField;
  }
}

JSON ve XML İşleme

JSON Manipulation

class JSONTools {
  static formatJSON(jsonString, indent = 2) {
    try {
      const parsed = JSON.parse(jsonString);
      return JSON.stringify(parsed, null, indent);
    } catch (error) {
      throw new Error("Geçersiz JSON formatı: " + error.message);
    }
  }

  static minifyJSON(jsonString) {
    try {
      const parsed = JSON.parse(jsonString);
      return JSON.stringify(parsed);
    } catch (error) {
      throw new Error("Geçersiz JSON formatı: " + error.message);
    }
  }

  static validateJSON(jsonString) {
    try {
      JSON.parse(jsonString);
      return { valid: true, error: null };
    } catch (error) {
      return { valid: false, error: error.message };
    }
  }

  static jsonToCSV(jsonArray) {
    if (!Array.isArray(jsonArray) || jsonArray.length === 0) {
      throw new Error("JSON array bekleniyor");
    }

    const headers = Object.keys(jsonArray[0]);
    return CSVTools.generateCSV(jsonArray, headers);
  }

  static flattenJSON(obj, prefix = "") {
    const flattened = {};

    for (const key in obj) {
      const newKey = prefix ? `${prefix}.${key}` : key;

      if (
        typeof obj[key] === "object" &&
        obj[key] !== null &&
        !Array.isArray(obj[key])
      ) {
        Object.assign(flattened, this.flattenJSON(obj[key], newKey));
      } else {
        flattened[newKey] = obj[key];
      }
    }

    return flattened;
  }
}

Markdown İşleme

Markdown Parser

class MarkdownTools {
  static toHTML(markdown) {
    return (
      markdown
        // Headers
        .replace(/^### (.*$)/gim, "<h3>$1</h3>")
        .replace(/^## (.*$)/gim, "<h2>$1</h2>")
        .replace(/^# (.*$)/gim, "<h1>$1</h1>")

        // Bold and Italic
        .replace(/\*\*(.*)\*\*/gim, "<strong>$1</strong>")
        .replace(/\*(.*)\*/gim, "<em>$1</em>")

        // Links
        .replace(/\[([^\]]+)\]\(([^)]+)\)/gim, '<a href="$2">$1</a>')

        // Code blocks
        .replace(/```([\s\S]*?)```/gim, "<pre><code>$1</code></pre>")
        .replace(/`([^`]+)`/gim, "<code>$1</code>")

        // Lists
        .replace(/^\* (.+)$/gim, "<li>$1</li>")
        .replace(/(<li>.*<\/li>)/gims, "<ul>$1</ul>")

        // Line breaks
        .replace(/\n/gim, "<br>")
    );
  }

  static toPlainText(markdown) {
    return markdown
      .replace(/\[([^\]]+)\]\([^)]+\)/gim, "$1")
      .replace(/\*\*(.*?)\*\*/gim, "$1")
      .replace(/\*(.*?)\*/gim, "$1")
      .replace(/`([^`]+)`/gim, "$1")
      .replace(/```[\s\S]*?```/gim, "")
      .replace(/^#+\s+/gim, "")
      .replace(/^\*\s+/gim, "• ")
      .trim();
  }

  static extractHeaders(markdown) {
    const headers = [];
    const lines = markdown.split("\n");

    lines.forEach((line, index) => {
      const match = line.match(/^(#{1,6})\s+(.+)$/);
      if (match) {
        headers.push({
          level: match[1].length,
          text: match[2],
          line: index + 1,
        });
      }
    });

    return headers;
  }

  static generateTOC(markdown) {
    const headers = this.extractHeaders(markdown);
    let toc = "";

    headers.forEach((header) => {
      const indent = "  ".repeat(header.level - 1);
      const anchor = header.text
        .toLowerCase()
        .replace(/[^\w\s-]/g, "")
        .replace(/\s+/g, "-");

      toc += `${indent}- [${header.text}](#${anchor})\n`;
    });

    return toc;
  }
}

Performance ve Optimizasyon

Büyük Metin Dosyaları İşleme

class LargeTextProcessor {
  static async processInChunks(text, chunkSize = 10000, processor) {
    const results = [];

    for (let i = 0; i < text.length; i += chunkSize) {
      const chunk = text.slice(i, i + chunkSize);
      const result = await processor(chunk, i);
      results.push(result);

      // Allow UI updates
      await new Promise((resolve) => setTimeout(resolve, 0));
    }

    return results;
  }

  static async searchInLargeText(text, searchTerm, caseInsensitive = true) {
    const results = [];
    const search = caseInsensitive ? searchTerm.toLowerCase() : searchTerm;
    const processText = caseInsensitive ? text.toLowerCase() : text;

    let index = 0;
    while (index < processText.length) {
      const foundIndex = processText.indexOf(search, index);
      if (foundIndex === -1) break;

      const contextStart = Math.max(0, foundIndex - 50);
      const contextEnd = Math.min(text.length, foundIndex + search.length + 50);

      results.push({
        index: foundIndex,
        context: text.slice(contextStart, contextEnd),
        line: text.slice(0, foundIndex).split("\n").length,
      });

      index = foundIndex + 1;
    }

    return results;
  }
}

Web Worker ile Arka Plan İşleme

// main thread
class BackgroundTextProcessor {
  constructor() {
    this.worker = new Worker('/text-worker.js');
    this.taskId = 0;
    this.pendingTasks = new Map();
  }

  async processText(text, operation, options = {}) {
    const taskId = ++this.taskId;

    return new Promise((resolve, reject) => {
      this.pendingTasks.set(taskId, { resolve, reject });

      this.worker.postMessage({
        taskId,
        text,
        operation,
        options
      });
    });
  }

  constructor() {
    this.worker.onmessage = (event) => {
      const { taskId, result, error } = event.data;
      const task = this.pendingTasks.get(taskId);

      if (task) {
        this.pendingTasks.delete(taskId);

        if (error) {
          task.reject(new Error(error));
        } else {
          task.resolve(result);
        }
      }
    };
  }
}

// text-worker.js
self.onmessage = function(event) {
  const { taskId, text, operation, options } = event.data;

  try {
    let result;

    switch (operation) {
      case 'hash':
        result = generateHash(text, options.algorithm);
        break;
      case 'analyze':
        result = analyzeText(text);
        break;
      case 'transform':
        result = transformText(text, options.transformation);
        break;
      default:
        throw new Error('Bilinmeyen operasyon: ' + operation);
    }

    self.postMessage({ taskId, result });
  } catch (error) {
    self.postMessage({ taskId, error: error.message });
  }
};

API Entegrasyonu

Dış Servis Entegrasyonları

class TextAPIServices {
  // Google Translate API entegrasyonu
  static async translateText(text, targetLang, sourceLang = "auto") {
    try {
      const response = await fetch("/api/translate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          text,
          targetLang,
          sourceLang,
        }),
      });

      const data = await response.json();
      return data.translatedText;
    } catch (error) {
      throw new Error("Çeviri hatası: " + error.message);
    }
  }

  // Grammar check API
  static async checkGrammar(text) {
    try {
      const response = await fetch("/api/grammar-check", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ text }),
      });

      const data = await response.json();
      return data.suggestions;
    } catch (error) {
      throw new Error("Gramer kontrolü hatası: " + error.message);
    }
  }

  // Sentiment analysis
  static async analyzeSentiment(text) {
    try {
      const response = await fetch("/api/sentiment", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ text }),
      });

      const data = await response.json();
      return {
        sentiment: data.sentiment, // positive, negative, neutral
        confidence: data.confidence,
        emotions: data.emotions,
      };
    } catch (error) {
      throw new Error("Duygu analizi hatası: " + error.message);
    }
  }
}

Pratik Kullanım Senaryoları

Blog Yazıları İçin Optimizasyon

class BlogOptimizer {
  static optimizeForSEO(content, targetKeyword) {
    const analysis = {
      // Temel metin analizi
      ...TextAnalytics.analyze(content),

      // SEO analizi
      ...SEOTextAnalyzer.calculateKeywordDensity(content, targetKeyword),

      // Okunabilirlik analizi
      ...ReadabilityAnalyzer.calculateFleschScore(content),

      // Meta description önerisi
      metaDescription: SEOTextAnalyzer.generateMetaDescription(content),

      // Header analizi
      headers: MarkdownTools.extractHeaders(content),
    };

    return {
      analysis,
      recommendations: this.generateRecommendations(analysis),
    };
  }

  static generateRecommendations(analysis) {
    const recommendations = [];

    if (analysis.words < 300) {
      recommendations.push("İçerik çok kısa. En az 300 kelime hedefleyin.");
    }

    if (analysis.density > 3) {
      recommendations.push(
        "Anahtar kelime yoğunluğu çok yüksek. Daha doğal kullanım tercih edin."
      );
    }

    if (analysis.score < 60) {
      recommendations.push("Metin çok karmaşık. Daha basit cümleler kullanın.");
    }

    if (analysis.avgSentenceLength > 20) {
      recommendations.push(
        "Cümleler çok uzun. Daha kısa cümleler tercih edin."
      );
    }

    return recommendations;
  }
}

E-posta Template Oluşturma

class EmailTemplateGenerator {
  static generatePlainText(html) {
    return html
      .replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, "")
      .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "")
      .replace(/<[^>]*>/g, "")
      .replace(/&nbsp;/g, " ")
      .replace(/&amp;/g, "&")
      .replace(/&lt;/g, "<")
      .replace(/&gt;/g, ">")
      .replace(/\n\s*\n/g, "\n\n")
      .trim();
  }

  static validateEmailContent(content) {
    const issues = [];

    // Spam trigger words
    const spamWords = ["free", "urgent", "act now", "limited time"];
    const lowerContent = content.toLowerCase();

    spamWords.forEach((word) => {
      if (lowerContent.includes(word)) {
        issues.push(`Spam trigger word detected: "${word}"`);
      }
    });

    // Link analysis
    const linkCount = (content.match(/https?:\/\/[^\s<>"]*/g) || []).length;
    if (linkCount > 10) {
      issues.push("Too many links detected");
    }

    // Image alt text
    const imagesWithoutAlt = content.match(/<img(?![^>]*alt=)[^>]*>/gi);
    if (imagesWithoutAlt) {
      issues.push("Images without alt text detected");
    }

    return issues;
  }
}

Testing ve Validation

Unit Test Örnekleri

// Jest test örnekleri
describe("TextTools", () => {
  describe("Hash Functions", () => {
    test("should generate consistent hash", async () => {
      const text = "Hello World";
      const hash1 = await HashTools.sha256(text);
      const hash2 = await HashTools.sha256(text);

      expect(hash1).toBe(hash2);
      expect(hash1).toHaveLength(64);
    });
  });

  describe("Case Transformations", () => {
    test("should convert to camelCase correctly", () => {
      expect(StringTools.toCamelCase("hello world")).toBe("helloWorld");
      expect(StringTools.toCamelCase("user-first-name")).toBe("userFirstName");
    });

    test("should handle edge cases", () => {
      expect(StringTools.toCamelCase("")).toBe("");
      expect(StringTools.toCamelCase("a")).toBe("a");
    });
  });

  describe("Text Analysis", () => {
    test("should count words correctly", () => {
      const analysis = TextAnalytics.analyze("Hello world. This is a test.");
      expect(analysis.words).toBe(6);
      expect(analysis.sentences).toBe(2);
    });
  });
});

Sonuç ve En İyi Uygulamalar

Özet Kontrol Listesi

Metin işleme yaparken:

  • [ ] Input validation yapın
  • [ ] Character encoding kontrol edin
  • [ ] Performance optimizasyonu düşünün
  • [ ] Error handling implement edin
  • [ ] Test coverage sağlayın

Güvenlik considerations:

  • [ ] XSS prevention (HTML escape)
  • [ ] Input sanitization
  • [ ] Rate limiting (API calls)
  • [ ] Data validation
  • [ ] Secure hash algorithms

Hemen Başlayın

Metin Araçları koleksiyonumuzla profesyonel metin işleme:

  1. Karakter dönüştürme - Case transformations, encoding
  2. Metin temizleme - HTML removal, whitespace normalization
  3. Hash oluşturma - MD5, SHA256, custom hashing
  4. İstatistik analizi - Word count, readability scoring
  5. Format dönüşümü - CSV, JSON, Markdown processing

Tüm metin işlemleri tarayıcınızda gerçekleştirilir, verileriniz güvende kalır.