Skip to main content

Chapter 8 - Strings and Text Editing (JavaScript)

Here's a JavaScript-flavoured version of the same concepts, with small JS examples for each idea.


String literals and escape sequences

You can write strings with single quotes, double quotes, or backticks. Backslash escape sequences like \', \", \n, \t, and \\ work the same way.

Example:

const spam = "That is Alice's cat.";
const spam2 = 'Say hi to Bob\'s mother.';
console.log("Hello there!\nHow are you?\nI'm doing fine.");

Raw strings with String.raw

JavaScript has no r prefix, but String.raw with a tagged template literal treats backslashes as literal characters.

Example:

console.log(String.raw`The file is in C:\Users\Alice\Desktop`);
console.log(String.raw`Hello...\n\n...world!`); // backslashes shown literally

Multiline strings (template literals)

Backtick strings (template literals) naturally span multiple lines, combining Python's triple-quote and f-string features.

Example:

console.log(`Dear Alice,

Can you feed Eve's cat this weekend?

Sincerely,
Bob`);

// JavaScript uses // or /* */ for comments, not multiline strings
/* This is a test program.
Written by Alice.
This serves as a multiline comment. */

String indexing and slicing

Access characters by index (starting at 0). Use .at() for negative indexes and .slice() for substrings.

Example:

const greeting = "Hello, world!";
console.log(greeting[0]); // 'H'
console.log(greeting.at(-1)); // '!'
console.log(greeting.slice(0, 5)); // 'Hello'
console.log(greeting.slice(7, -1)); // 'world'
console.log(greeting.slice(7)); // 'world!'

includes() (equivalent of in)

You can test if a substring appears inside another string using .includes().

Example:

console.log("Hello, world".includes("Hello"));      // true
console.log("Hello, world".includes("HELLO")); // false
console.log(!"cats and dogs".includes("cats")); // false

Template literals (like f-strings)

Backtick strings with ${} embed expressions directly, instead of manual concatenation.

Example:

const name = "Al";
const age = 4000;
console.log(`My name is ${name}. I am ${age} years old.`);
console.log(`In ten years I will be ${age + 10}`);

Literal braces (no special escaping needed — only ${} is interpolated):

console.log(`{name}`);  // prints {name}

Older formatting: concatenation

Before template literals, string concatenation was the main approach.

Example:

const name = "Al";
const age = 4000;
console.log("My name is " + name + ". I am " + age + " years old.");

Changing case: toUpperCase(), toLowerCase()

toUpperCase() / toLowerCase() return new strings. JavaScript has no built-in isupper() / islower(), but you can compare against the converted version.

Example:

const spam = "Hello, world!";
console.log(spam.toUpperCase()); // 'HELLO, WORLD!'
console.log(spam.toLowerCase()); // 'hello, world!'
console.log("HELLO" === "HELLO".toUpperCase()); // true (all upper)
console.log("abc123" === "abc123".toLowerCase()); // true (all lower)

Case-insensitive check:

const feeling = prompt("How are you?");
if (feeling.toLowerCase() === "great") {
console.log("I feel great too.");
} else {
console.log("I hope the rest of your day is good.");
}

Character type checks with regex

JavaScript has no built-in isalpha(), isalnum(), isdecimal(), isspace(), or istitle(), but regex handles all of these.

Example:

console.log(/^[a-zA-Z]+$/.test("hello"));          // true (only letters)
console.log(/^[a-zA-Z0-9]+$/.test("hello123")); // true (letters and numbers)
console.log(/^\d+$/.test("123")); // true (only digits)
console.log(/^\s+$/.test(" ")); // true (only whitespace)

Simple input validation:

let age;
while (true) {
age = prompt("Enter your age:");
if (/^\d+$/.test(age)) break;
console.log("Please enter a number for your age.");
}

let password;
while (true) {
password = prompt("Select a new password (letters and numbers only):");
if (/^[a-zA-Z0-9]+$/.test(password)) break;
console.log("Passwords can only have letters and numbers.");
}

startsWith() and endsWith()

Check if a string begins or ends with a given substring.

Example:

const s = "Hello, world!";
console.log(s.startsWith("Hello")); // true
console.log(s.endsWith("world!")); // true
console.log("abc123".startsWith("abc")); // true

Joining and splitting strings

  • array.join('sep') builds one string from many.
  • 'text'.split() does not split on whitespace by default in JS — use .split(/\s+/) or .split(' ').

Examples:

console.log(["cats", "rats", "bats"].join(", "));  // 'cats, rats, bats'
console.log(["My", "name", "is", "Simon"].join(" ")); // 'My name is Simon'

console.log("My name is Simon".split(" ")); // ['My', 'name', 'is', 'Simon']
console.log("MyABCnameABCisABCSimon".split("ABC")); // ['My', 'name', 'is', 'Simon']

Split multiline string into lines:

const spam = `Dear Alice,
There is a milk bottle in the fridge
that is labeled "Milk Experiment."

Please do not drink it.
Sincerely,
Bob`;
const lines = spam.split("\n");

Text alignment: padStart(), padEnd()

These methods pad strings to a given total width, optionally with a fill character. JavaScript has no built-in center().

Example:

console.log("Hello".padStart(10));          // '     Hello'
console.log("Hello".padEnd(10, "-")); // 'Hello-----'

// center helper
function center(str, width, fill = " ") {
const pad = Math.max(0, width - str.length);
const left = Math.floor(pad / 2);
return fill.repeat(left) + str + fill.repeat(pad - left);
}
console.log(center("Hello", 20, "=")); // '=======Hello========'

Trimming whitespace or specific characters: trim(), trimStart(), trimEnd()

Remove whitespace from the ends of a string. JavaScript's trim doesn't accept a character set, but you can use regex for that.

Example:

const spam = "   Hello, World   ";
console.log(spam.trim()); // 'Hello, World'
console.log(spam.trimStart()); // 'Hello, World '
console.log(spam.trimEnd()); // ' Hello, World'

Strip specific characters (with regex):

const spam2 = "SpamSpamBaconSpamEggsSpamSpam";
console.log(spam2.replace(/^[ampS]+|[ampS]+$/g, "")); // 'BaconSpamEggs'

Unicode code points: charCodeAt() and String.fromCharCode()

charCodeAt() gives the integer code point for a character; String.fromCharCode() does the reverse.

Example:

console.log("A".charCodeAt(0));   // 65
console.log("!".charCodeAt(0)); // 33
console.log(String.fromCharCode(65)); // 'A'
console.log(String.fromCharCode("A".charCodeAt(0) + 1)); // 'B'

Clipboard access

In the browser, use the async Clipboard API. In Node.js, use a package like clipboardy.

Example (browser):

await navigator.clipboard.writeText("Hello, world!");
const text = await navigator.clipboard.readText();
console.log(text); // 'Hello, world!'

Alternating-case program (browser):

let text = await navigator.clipboard.readText();
let altText = "";
let makeUpper = false;

for (const ch of text) {
altText += makeUpper ? ch.toUpperCase() : ch.toLowerCase();
makeUpper = !makeUpper;
}

await navigator.clipboard.writeText(altText);
console.log(altText);

Project: bulletPointAdder (add bullets to lines)

Reads text from clipboard, adds * to each line, writes back to clipboard using .split('\n') and .join('\n').

Core version (browser):

let text = await navigator.clipboard.readText();
const lines = text.split("\n");
for (let i = 0; i < lines.length; i++) {
lines[i] = "* " + lines[i];
}
text = lines.join("\n");
await navigator.clipboard.writeText(text);

Project: Pig Latin translator

Transforms each word into Pig Latin while preserving punctuation and capitalization using string methods like split, regex character checks, toLowerCase, toUpperCase, and join.

Very compact sketch:

const message = prompt("Enter the English message to translate into pig latin:");
const VOWELS = ["a", "e", "i", "o", "u", "y"];
const pigLatin = [];

for (let word of message.split(" ")) {
let prefixNon = "";
while (word.length > 0 && !/[a-zA-Z]/.test(word[0])) {
prefixNon += word[0];
word = word.slice(1);
}
if (word.length === 0) {
pigLatin.push(prefixNon);
continue;
}

let suffixNon = "";
while (!/[a-zA-Z]/.test(word.at(-1))) {
suffixNon = word.at(-1) + suffixNon;
word = word.slice(0, -1);
}

const wasUpper = word === word.toUpperCase();
const wasTitle = word[0] === word[0].toUpperCase() && word.slice(1) === word.slice(1).toLowerCase();
word = word.toLowerCase();

let prefixCons = "";
while (word.length > 0 && !VOWELS.includes(word[0])) {
prefixCons += word[0];
word = word.slice(1);
}

if (prefixCons) {
word = word + prefixCons + "ay";
} else {
word = word + "yay";
}

if (wasUpper) {
word = word.toUpperCase();
} else if (wasTitle) {
word = word[0].toUpperCase() + word.slice(1);
}

pigLatin.push(prefixNon + word + suffixNon);
}

console.log(pigLatin.join(" "));

Overall idea of the chapter

The chapter's main message is: JavaScript has a strong set of string methods that mirror Python's capabilities. Template literals combine f-string interpolation with multiline strings in one syntax. The core operations (searching, splitting, trimming, case conversion) are nearly identical between the two languages, and even complex programs like a Pig Latin translator translate directly.