Reversing strings correctly
| Input | Reversed by character | split('').reverse() |
|---|---|---|
| noël | lëon | l̈eon |
| 👍🏽 ok | ko 👍🏽 | ko �🁍� |
| 🇯🇵🇫🇷 | 🇫🇷🇯🇵 | �🇫🇵🇯� |
| 👩💻 | 👩💻 | ���� |
In the last column, emoji split into two halves show up as �, the accent in noël (written as e plus a combining diaeresis) lands on the wrong letter, 👍🏽 turns into unrelated and broken characters, and the flags turn into other letter pairs or separate letters.
Reversing a string in code
// Correct for emoji, flags and accents
const reverse = (s) =>
[...new Intl.Segmenter().segment(s)].map((x) => x.segment).reverse().join('');
[...'abc'].reverse().join(''); // by code point: fine for most emoji, breaks flags and ZWJ sequences
'abc'.split('').reverse().join(''); // by UTF-16 code unit: breaks any emoji
s[::-1] # by code point: breaks flags, ZWJ emoji and combining accents
# By grapheme cluster: pip install regex
import regex
"".join(reversed(regex.findall(r"\X", s)))
" ".join(reversed(s.split())) # reverse word order
rev file.txt # reverse each line
tac file.txt # reverse line order (GNU; on macOS: tail -r)
Want lines in a sorted order instead? Use sort lines. Counting the characters in a string? The word counter shows grapheme, code point, UTF-16 and byte counts.
Frequently asked questions
Why not just use split("").reverse().join("")?
Because it reverses UTF-16 code units, not characters. Most emoji are two code units, so reversing them swaps the halves and produces broken characters (shown as �). Flags, skin tones, emoji with zero-width joiners and letters with a combining accent are several code points that must stay in order. This tool reverses by grapheme cluster, what you see as one character, so all of them survive.
What’s the difference between the modes?
“Characters” reverses the whole text, so the last line comes first and is spelled backwards. “Word order” keeps each word intact but reverses their order on every line. “Line order” keeps lines intact and puts the last line first, like tac. “Each line” spells every line backwards but keeps the lines where they are.
How do I check if a word is a palindrome?
Reverse it with “Characters”: if the text is unchanged, a note under the tool says it’s a palindrome. That check is exact, so for phrases like “A man, a plan, a canal: Panama” remove spaces and punctuation and convert to lowercase first.
Does it work with right-to-left languages?
Yes, Arabic and Hebrew are reversed by character like any other text. Keep in mind that the text is already stored first letter first and displayed right to left by the browser, so the reversed text will display left to right.