לדלג לתוכן

2.8 מחרוזות הרצאה

מחרוזות - Strings

כבר ראינו מחרוזות בשיעורים הקודמים, אבל עכשיו נעמיק ונכיר את כל הכלים שיש לנו לעבוד איתן.
מחרוזות ב-JavaScript הן immutable - בדיוק כמו בפייתון. כל מתודה שנראה מחזירה מחרוזת חדשה ולא משנה את המקורית.


תבניות מחרוזת - Template Literals

הדרך המודרנית ליצור מחרוזות עם ערכים דינמיים. משתמשים ב-backticks (`) במקום גרשיים:

const name = "Alice";
const age = 25;

// old way - string concatenation
const msg1 = "My name is " + name + " and I am " + age + " years old";

// modern way - template literal
const msg2 = `My name is ${name} and I am ${age} years old`;

console.log(msg2); // "My name is Alice and I am 25 years old"

בתוך ${} אפשר לשים כל ביטוי של JavaScript:

const price = 100;
const tax = 0.17;

console.log(`Total: ${price * (1 + tax)}`); // "Total: 117"
console.log(`Is adult: ${age >= 18}`);       // "Is adult: true"
console.log(`Name length: ${name.length}`);  // "Name length: 5"

בפייתון זה מקביל ל-f-strings:

// Python equivalent:
// msg = f"My name is {name} and I am {age} years old"
// total = f"Total: {price * (1 + tax)}"

מחרוזות מרובות שורות - Multi-line Strings

עם backticks אפשר לכתוב מחרוזות שפרוסות על כמה שורות:

const html = `
<div class="card">
  <h2>${name}</h2>
  <p>Age: ${age}</p>
</div>
`;

console.log(html);

בפייתון הייתם משתמשים בגרשיים משולשים:

// Python equivalent:
// html = f"""
// <div class="card">
//   <h2>{name}</h2>
//   <p>Age: {age}</p>
// </div>
// """

אורך מחרוזת - length

const str = "Hello World";

console.log(str.length); // 11

שימו לב - ב-JavaScript length הוא property, לא פונקציה. לא צריך סוגריים.
בפייתון len(str) היא פונקציה.


charAt ואינדקס

const str = "JavaScript";

// using index (like Python)
console.log(str[0]);     // "J"
console.log(str[4]);     // "S"

// using charAt (same result)
console.log(str.charAt(0)); // "J"
console.log(str.charAt(4)); // "S"

// difference: index returns undefined for out of range, charAt returns ""
console.log(str[100]);       // undefined
console.log(str.charAt(100)); // ""

חיפוש בתוך מחרוזת

indexOf - מוצא את המיקום הראשון

const str = "Hello World Hello";

console.log(str.indexOf("World")); // 6
console.log(str.indexOf("Hello")); // 0 (first occurrence)
console.log(str.indexOf("xyz"));   // -1 (not found)

// search from a specific position
console.log(str.indexOf("Hello", 1)); // 12 (second occurrence)

includes - בודק אם קיים

console.log(str.includes("World")); // true
console.log(str.includes("xyz"));   // false

startsWith ו-endsWith

const filename = "report.pdf";

console.log(filename.startsWith("report")); // true
console.log(filename.endsWith(".pdf"));      // true
console.log(filename.endsWith(".doc"));      // false

const url = "https://example.com";
console.log(url.startsWith("https")); // true

בפייתון יש את אותן מתודות בדיוק:

// Python equivalent:
// str.index("World")       -> indexOf
// "World" in str           -> includes
// str.startswith("report") -> startsWith
// str.endswith(".pdf")     -> endsWith

חיתוך מחרוזת - slice ו-substring

slice

const str = "JavaScript";

console.log(str.slice(0, 4));  // "Java"
console.log(str.slice(4));     // "Script"
console.log(str.slice(-6));    // "Script" (from the end)
console.log(str.slice(0, -6)); // "Java" (everything except last 6)
console.log(str.slice(2, 5));  // "vaS"

substring

console.log(str.substring(0, 4)); // "Java"
console.log(str.substring(4));    // "Script"

ההבדל העיקרי: slice תומך באינדקסים שליליים, substring לא.
מומלץ להשתמש ב-slice - הוא יותר גמיש ומתנהג כמו slicing בפייתון.

// Python equivalent:
// str[0:4]   -> str.slice(0, 4)
// str[4:]    -> str.slice(4)
// str[-6:]   -> str.slice(-6)
// str[:-6]   -> str.slice(0, -6)

המרת רישיות - Case Conversion

const str = "Hello World";

console.log(str.toUpperCase()); // "HELLO WORLD"
console.log(str.toLowerCase()); // "hello world"

בפייתון: str.upper() ו-str.lower().


חיתוך רווחים - trim

const str = "   Hello World   ";

console.log(str.trim());      // "Hello World"
console.log(str.trimStart()); // "Hello World   "
console.log(str.trimEnd());   // "   Hello World"

שימושי במיוחד לטיפול בקלט מהמשתמש:

const userInput = "   alice@test.com   ";
const email = userInput.trim();
console.log(email); // "alice@test.com"

בפייתון: str.strip(), str.lstrip(), str.rstrip().


החלפת טקסט - replace ו-replaceAll

replace - מחליפה את ההתאמה הראשונה

const str = "Hello World Hello";

console.log(str.replace("Hello", "Hi")); // "Hi World Hello"

replaceAll - מחליפה את כל ההתאמות

console.log(str.replaceAll("Hello", "Hi")); // "Hi World Hi"

דוגמה מעשית:

// sanitize user input
const input = "  Hello   World  ";
const cleaned = input.trim().replaceAll("  ", " ");
console.log(cleaned); // "Hello World"

// replace special characters
const filename = "my file (copy).txt";
const safe = filename.replaceAll(" ", "_").replaceAll("(", "").replaceAll(")", "");
console.log(safe); // "my_file_copy.txt"

בפייתון: str.replace("old", "new") מחליפה את כל ההתאמות כברירת מחדל (בניגוד ל-JavaScript!).


פיצול מחרוזת - split

ממירה מחרוזת למערך:

const csv = "Alice,Bob,Charlie,Diana";
const names = csv.split(",");
console.log(names); // ["Alice", "Bob", "Charlie", "Diana"]

const sentence = "Hello World How Are You";
const words = sentence.split(" ");
console.log(words); // ["Hello", "World", "How", "Are", "You"]

// split every character
const chars = "Hello".split("");
console.log(chars); // ["H", "e", "l", "l", "o"]

// limit the number of parts
const parts = csv.split(",", 2);
console.log(parts); // ["Alice", "Bob"]

ובכיוון ההפוך - join ממיר מערך למחרוזת:

const arr = ["Hello", "World"];
console.log(arr.join(" "));  // "Hello World"
console.log(arr.join("-"));  // "Hello-World"
console.log(arr.join(""));   // "HelloWorld"

בפייתון: str.split(",") ו-",".join(list) - אותו רעיון בדיוק.


חזרה - repeat

const str = "Ha";

console.log(str.repeat(3)); // "HaHaHa"

// create a separator line
console.log("-".repeat(40)); // "----------------------------------------"

// padding with custom character
const padded = "5".repeat(3);
console.log(padded); // "555"

בפייתון: "Ha" * 3.


ריפוד - padStart ו-padEnd

const num = "5";

console.log(num.padStart(3, "0")); // "005"
console.log(num.padEnd(3, "0"));   // "500"

// useful for formatting
const hours = "9";
const minutes = "5";
const time = `${hours.padStart(2, "0")}:${minutes.padStart(2, "0")}`;
console.log(time); // "09:05"

// table-like alignment
const items = [
  { name: "Apple", price: 5 },
  { name: "Banana", price: 12 },
  { name: "Cherry", price: 120 }
];

items.forEach((item) => {
  console.log(`${item.name.padEnd(10)} ${String(item.price).padStart(5)}`);
});
// Apple          5
// Banana        12
// Cherry       120

בפייתון: str.zfill(3) למספרים, או str.ljust(10) ו-str.rjust(5).


התאמה עם רגקס - match

הקדמה קצרה ל-regular expressions. נעמיק בנושא בהמשך, אבל הנה הבסיס:

const str = "My phone is 050-1234567 and also 052-9876543";

// find phone numbers
const phones = str.match(/\d{3}-\d{7}/g);
console.log(phones); // ["050-1234567", "052-9876543"]

// find all numbers
const numbers = str.match(/\d+/g);
console.log(numbers); // ["050", "1234567", "052", "9876543"]

// check if matches pattern
const email = "test@example.com";
const isEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
console.log(isEmail); // true

בפייתון: re.findall(pattern, str).


השוואת מחרוזות - localeCompare

להשוואה שמתחשבת בשפה ובתרבות:

const a = "apple";
const b = "banana";

console.log(a.localeCompare(b)); // -1 (a comes before b)
console.log(b.localeCompare(a)); // 1 (b comes after a)
console.log(a.localeCompare(a)); // 0 (equal)

// useful for sorting
const names = ["Charlie", "Alice", "Bob"];
names.sort((a, b) => a.localeCompare(b));
console.log(names); // ["Alice", "Bob", "Charlie"]

// case-insensitive comparison
console.log("a".localeCompare("A", undefined, { sensitivity: "base" })); // 0

מחרוזות הן Immutable

כל המתודות שראינו מחזירות מחרוזת חדשה. המקור לא משתנה:

const str = "Hello";

str.toUpperCase();
console.log(str); // "Hello" - unchanged!

const upper = str.toUpperCase();
console.log(upper); // "HELLO" - new string

// cannot modify characters directly
str[0] = "J"; // does nothing (no error, but doesn't work)
console.log(str); // "Hello"

זה בדיוק כמו בפייתון - מחרוזות הן immutable בשתי השפות.


השוואת מתודות - JavaScript מול Python

פעולה JavaScript Python
אורך str.length len(str)
אותיות גדולות str.toUpperCase() str.upper()
אותיות קטנות str.toLowerCase() str.lower()
חיתוך רווחים str.trim() str.strip()
חיפוש str.includes("x") "x" in str
מיקום str.indexOf("x") str.index("x")
מתחיל ב str.startsWith("x") str.startswith("x")
מסתיים ב str.endsWith("x") str.endswith("x")
חיתוך str.slice(0, 4) str[0:4]
החלפה str.replaceAll("a", "b") str.replace("a", "b")
פיצול str.split(",") str.split(",")
חזרה str.repeat(3) str * 3
אינטרפולציה `Hi ${name}` f"Hi {name}"
מרובת שורות `line1\nline2` """line1\nline2"""

דפוסים מעשיים

בדיקת מחרוזת ריקה

const str = "";

// check if empty or only whitespace
if (!str.trim()) {
  console.log("String is empty or whitespace");
}

המרת camelCase ל-kebab-case

function toKebabCase(str) {
  return str.replace(/([A-Z])/g, "-$1").toLowerCase();
}

console.log(toKebabCase("backgroundColor")); // "background-color"
console.log(toKebabCase("fontSize"));         // "font-size"

חילוץ סיומת קובץ

function getExtension(filename) {
  return filename.slice(filename.lastIndexOf(".") + 1);
}

console.log(getExtension("photo.jpg"));  // "jpg"
console.log(getExtension("file.tar.gz")); // "gz"

קיצור מחרוזת

function truncate(str, maxLength) {
  if (str.length <= maxLength) return str;
  return str.slice(0, maxLength - 3) + "...";
}

console.log(truncate("Hello World", 8)); // "Hello..."
console.log(truncate("Hi", 8));          // "Hi"

סיכום

  • Template literals (backticks) - הדרך המודרנית ליצור מחרוזות עם ערכים דינמיים
  • length - property (לא פונקציה)
  • חיפוש: indexOf, includes, startsWith, endsWith
  • חיתוך: slice (מועדף) ו-substring
  • המרה: toUpperCase, toLowerCase
  • ניקוי: trim, trimStart, trimEnd
  • החלפה: replace (ראשון) ו-replaceAll (כולם)
  • פיצול: split למערך, join חזרה למחרוזת
  • עיצוב: padStart, padEnd, repeat
  • מחרוזות הן immutable - כל מתודה מחזירה מחרוזת חדשה