Position-based codepoint compare
Character diff is the finest-grained comparison in this hub. The split between text A and text B is a line containing exactly ---. The tool walks both strings in parallel; for every index i it checks whether A[i] equals B[i]. If the characters match, the character is appended to the output. If they differ, the pair is wrapped [-A[i]|B[i]-].
Comparison is position-based, not LCS. Inserting a single character at the start of B will mark every subsequent character as a change because the indices have shifted by one. Use Levenshtein distance to get the minimum edit count, or longest common substring to find the largest matching block.
String length asymmetry is handled by treating missing characters as empty strings, so the longer side's tail is emitted as a series of [-|extra-] or [-extra|-] markers. Comparison is case sensitive and treats whitespace as content; a tab in A versus a space in B produces a marker.
How to use character-level diff
- 1Paste string A into the input panel, then a line with
---, then string B. - 2The character diff appears in the output panel with
[-A|B-]markers on differing positions. - 3Click Copy to copy the marked-up string, or Download to save it.
- 4For an edit count rather than a marked-up view, switch to Levenshtein distance.
- 5For the largest unbroken matching span use longest common substring.
Keyboard shortcuts
Drive TextResult without touching the mouse.
| Shortcut | Action |
|---|---|
| Ctrl F | Open the find & replace panel inside the input Plus |
| Ctrl Z | Undo the last input change |
| Ctrl Shift Z | Redo |
| Ctrl Shift Enter | Toggle fullscreen focus on the editor Plus |
| Esc | Close find & replace, or exit fullscreen |
| Ctrl K | Open the command palette to jump to any tool Plus |
| Ctrl S | Save current workflow draft Plus |
| Ctrl P | Run a saved workflow Plus |
How the character diff works
Position-based equality
For each index i the tool checks A[i] === B[i]. No alignment heuristic, no LCS. Inserting a single character cascades as a long string of changes.
Inline marker for differences
Differing characters are wrapped [-A[i]|B[i]-]. The marker is plain ASCII, easy to read and easy to paste into a chat or a review.
Case and whitespace sensitive
A versus a registers as a change. Tabs, spaces, and line breaks all count as content and are compared like any other character.
Unequal lengths handled
When one side is longer, missing positions on the shorter side are treated as empty strings; the tail emits [-extra|-] or [-|extra-] markers depending on direction.
Three-hyphen separator
The split between A and B is a line containing exactly ---. The tool requires this marker to know where A ends and B begins.
Worked example
Position 0 differs (k vs s), itt matches, position 4 differs (e vs i), then n matches and g trails on B. For a single edit-count number, see Levenshtein distance.
kitten --- sitting
[-k|s-]itt[-e|i-]n[-|g-][-|-]
Settings reference
| Behaviour | Effect on output |
|---|---|
| Separator | A line containing exactly --- splits text A from text B. |
| Granularity | Per character (per UTF-16 code unit, the JavaScript default). |
| Match rule | Exact equality on each codepoint, including case. |
| Output for matches | Character emitted as-is. |
| Output for changes | Wrapped [-A-char|B-char-]. |
| Unequal lengths | Tail emitted with empty placeholder on the missing side. |
| Missing separator | Output prompts for two halves split by ---. |
FAQ
Why does an inserted character mark the rest of the string?
i shifts everything to its right by one position, so they all stop matching their counterparts. For an alignment-aware view use longest common substring or count edits with Levenshtein.How are surrogate pairs and emoji handled?
Are tabs and spaces compared?
\t versus (a regular space) produces a marker.