How to Escape a Pipe (|) in a Markdown Table
By MarkdownTables.com editorial teamUpdated
On this page
Which escape works where
| Method | Plain text | Inside `code` | Link text | Notes |
|---|---|---|---|---|
\| | ✅ Shows | | ✅ Shows | | ✅ Shows | | The standard answer; the backslash is removed |
| or | | ✅ Shows | | ❌ Shows | | ✅ Shows | | Entities are not decoded in code spans |
| / | | ✅ Shows | | ❌ Shows the entity | ✅ Shows | | Named HTML5 entities |
<code>a|b</code> | n/a | ✅ HTML code element | n/a | Fallback where \| misbehaves |
| Backticks only | — | ❌ Splits the cell | — | The most common mistake |
\vert in math | — | — | — | Inside $…$ on GitHub; see math in tables |
| Choice | Meaning |
| :---------- | :---------------------- |
| Yes \| No | Either answer is valid |
| A | B | Same result with an entity || Choice | Meaning |
|---|---|
| Yes | No | Either answer is valid |
| A | B | Same result with an entity |
Why a pipe splits the cell even inside backticks
The GFM spec splits each table row into cells on unescaped pipes before it parses the inline content of the cells. At that point it doesn't know about code spans, links or math, so a | inside backticks ends the cell just like any other. The spec's own example shows the fix: a \| inside a code span becomes a literal pipe, because the table extension removes the backslash when it builds the cell.
This differs from the rest of Markdown, where a backslash inside a code span is always shown as typed. It is the one place a backslash escape works inside code.
How do I escape a pipe inside a code span?
Escape each pipe with a backslash inside the backticks. Shell pipelines, logical OR and bitwise operators all work the same way:
| Command | What it does |
| :--------------------------- | :------------------------ |
| `ps aux \| grep node` | Find running Node processes |
| `cat app.log \| wc -l` | Count log lines |
| `a \|\| b` | Logical OR || Command | What it does |
|---|---|
ps aux | grep node | Find running Node processes |
cat app.log | wc -l | Count log lines |
a || b | Logical OR |
Some editors warn you about this. JetBrains IDEs, for example, include a Markdown inspection for pipes in code spans inside tables. The table formatter keeps \| intact when it realigns the columns.
Regex alternation (OR) in a table
Regular expressions are where unescaped pipes bite most, because alternation uses |. Escape each one; readers see the normal regex.
| Pattern | Matches |
| :--------------------- | :----------------------- |
| `^(cat\|dog)s?$` | cat, cats, dog, dogs |
| `\.(jpe?g\|png\|gif)$` | Image file extensions || Pattern | Matches |
|---|---|
^(cat|dog)s?$ | cat, cats, dog, dogs |
\.(jpe?g|png|gif)$ | Image file extensions |
The Markdown backslash disappears, so the rendered (cat|dog) is an alternation, as intended. A regex that needs a literal pipe (\| in regex terms) is the hard case: in a code span you would have to write a backslash right before an escaped pipe, and \\| splits the cell (see the double backslash pitfall). Write it as HTML, <code>\\|</code>, which renders \|, or move the pattern into a code block under the table.
Pipes in links and Obsidian wikilinks
A pipe in link text needs the same escape. Obsidian wikilinks with an alias use a pipe as the separator, so inside a table write [[Note\|Alias]]; Obsidian's own help documents this.
| Page | Note |
| :------------------------------------------ | :---------- |
| [Guide \| API](https://example.com/guide) | Escaped pipe in link text |
| [[Project plan\|Plan]] | Obsidian wikilink alias || Page | Note |
|---|---|
| Guide | API | Escaped pipe in link text |
| [[Project plan|Plan]] | Obsidian wikilink alias |
The wikilink row renders as a link only in Obsidian; elsewhere it stays as text.
Open in editor : Escaped pipes in a Markdown link and an Obsidian wikilinkIn a URL, don't escape the pipe with a backslash; percent-encode it as %7C. That is valid in every URL and never splits the cell.
HTML entities and the <code> fallback
HTML character references are decoded after the row is split, so they never start a cell. Use them in plain text, or inside an HTML <code> element if a renderer shows the backslash in Markdown code spans:
| Method | Renders as |
| :-------------------------- | :--------- |
| <code>a|b</code> | HTML code element with an entity |
| x | y | Named entity in plain text || Method | Renders as |
|---|---|
a|b | HTML code element with an entity |
| x | y | Named entity in plain text |
Inside <code>…</code> a raw | still splits the cell, because the splitter doesn't know about HTML tags either. Write the entity there.
Pipes in headers, math and converted data
- Header cells follow the same rule. A header such as
Input | Outputmust be writtenInput \| Output, or the header gains a column and no longer matches the delimiter row, so the whole table stops rendering. - Math. Absolute values and norms in
$…$contain pipes too. Write\vert(or\lvert x \rvert) inside the math instead of|; the math in tables guide has examples. - Converted data. CSV, Excel or SQL output often contains pipes (shell commands, enum lists like
draft|live). The CSV to Markdown converter and the other converters on this site escape every pipe as\|, including pipes inside backticks, so paste the data there instead of escaping by hand. - Other flavors. MultiMarkdown, Pandoc pipe tables and kramdown also accept
\|in plain text. Their handling of pipes inside code spans may differ from GFM, so preview anything that mixes the two.
Pipe escaping by platform
| Platform | `\|` in text | `\|` in code spans | `|` in text | `|` in code |
|---|---|---|---|---|
GitHub (GFM)Follows the GFM spec: \| works everywhere in a cell, and the backslash is removed. | Yes | Yes | Yes | No: Prints literally |
| GitLab (GLFM)Older versions displayed the backslash inside code spans (GitLab issue 322503). | Yes | Partly: Preview on older versions | Yes | No: Prints literally |
ObsidianWikilink aliases in tables need [[Note\|Alias]]. | Yes | Partly: Preview it | Yes | No: Prints literally |
✅ supported · ⚠️ partly or with a workaround · ❌ not supported · Last verified October 2026
Renderers that predate the GFM spec, or implement tables differently, may keep the backslash inside code spans. Preview there, and use <code>a|b</code> if it shows.
Common mistakes (broken vs. fixed)
Relying on backticks
| Command | Purpose |
| ---------------------- | ------------------- |
| `ps aux | grep node` | Find Node processes || Command | Purpose |
|---|---|
| `ps aux | grep node` |
Preview shows what GitHub renders: the cell splits at the pipe, both halves show stray backticks, and the description is dropped as an extra cell.
\| inside the code span| Command | Purpose |
| ----------------------- | ------------------- |
| `ps aux \| grep node` | Find Node processes || Command | Purpose |
|---|---|
ps aux | grep node | Find Node processes |
Using | inside backticks
| Pattern | Matches |
| ---------------- | ----------- |
| `(cat|dog)` | cat or dog || Pattern | Matches |
|---|---|
(cat|dog) | cat or dog |
Use \| inside code spans; keep | for plain text.
Escaping the backslash instead of the pipe
\\| is an escaped backslash followed by a bare pipe, so the cell still splits. You can't show a backslash directly before a pipe with \| alone; write \\| (an escaped backslash, then the entity) instead.
\\| escapes the backslash, not the pipe| Pattern | Note |
| ------- | ---- |
| a \\| b | Backslash escaped instead of the pipe || Pattern | Note |
|---|---|
| a \ | b |
The note text lands in a third cell, which GFM drops because the header has two columns.
A cell that ends in a backslash
Windows paths and similar values can end with \. If no space separates it from the next pipe, the backslash escapes that pipe and two cells merge. Add a space or double the backslash. The table generator doubles a trailing backslash for you.
\| swallows the cell boundary| Path | Type |
| ---------- | --------- |
| C:\Temp\| folder || Path | Type |
|---|---|
| C:\Temp| folder |
\\ before the pipe| Path | Type |
| ---------- | --------- |
| C:\Temp\\ | folder || Path | Type |
|---|---|
| C:\Temp\ | folder |
Unescaped pipes in plain text usually show up as rows with more cells than the header. The table validator reports those rows with their line numbers.
When escaping gets unreadable
A table full of \| is hard to read and hard to edit. When the cells hold long commands or patterns, give each one a short label in the table and put the real code in a fenced code block below it, where pipes need no escaping:
| Step | Command |
| ---- | -------------- |
| 1 | See "Filter logs" below |
### Filter logs
```sh
journalctl -u app | grep -E "ERROR|WARN" | tail -n 50
```An HTML table with <code>…|…</code> is the other option when you can't trust a renderer's handling of \|. For other cell content, see text formatting in tables and line breaks, or go back to the Markdown table syntax overview.
Frequently asked questions
How do I escape a pipe in a Markdown table?
Put a backslash in front of it: \|. The pipe is shown and no new column starts. In plain text | works too.
How do I escape a pipe inside a code span in a table?
Type \| inside the backticks: ps aux \| grep node between backticks renders as ps aux | grep node. GFM splits cells before it reads code spans, so backticks alone don't protect the pipe, and GitHub removes the backslash from the rendered code.
Why does | show up literally in my table?
It is inside a code span. Entities are not decoded in code, so a|b between backticks prints the entity text. Use \| in code spans and keep | for plain text, or write <code>a|b</code> in HTML.
How do I write a regex with | (OR) in a Markdown table?
Escape every alternation pipe inside the backticks: ^(cat\|dog)$. Readers see ^(cat|dog)$. For long patterns, put the regex in a code block below the table and refer to it.
How do I write || (logical OR) in a table cell?
Escape both pipes: a \|\| b, inside backticks if you want it formatted as code. Each | needs its own backslash.
How do I use an Obsidian wikilink alias inside a table?
Escape the alias pipe: [[Note\|Alias]]. Without the backslash, Obsidian splits the link across two cells.
Does a pipe in a URL break the table?
Yes, an unescaped | anywhere in the row starts a new cell, including inside a link target. Percent-encode it as %7C in the URL, which also keeps the link valid everywhere.