Question
How can I remove every character from a string that is not a letter (a-z or A-Z), digit (0-9), or space?
For example, I want a JavaScript function that keeps letters, numbers, and spaces while removing punctuation and symbols.
Short Answer
You will learn how to use JavaScript regular expressions to keep only allowed characters in a string. This includes understanding character classes, negation, global replacement, whitespace choices, and Unicode-friendly alternatives.
Concept
A regular expression (regex) is a pattern used to find text. In this case, the goal is to find every character that is not allowed and replace it with an empty string.
The allowed ASCII characters are:
A-Z— uppercase English lettersa-z— lowercase English letters0-9— digits- a literal space — spaces between words
In a regex character class, square brackets describe a set of characters. Placing ^ immediately after the opening bracket means not these characters.
/[^a-zA-Z0-9 ]/g
This pattern means: “match every character that is not an English letter, digit, or ordinary space.” Calling replace() with an empty replacement removes each match.
This is useful for sanitizing display names, creating restricted identifiers, cleaning imported data, and validating text before storing or processing it. However, cleaning text is not the same as security validation: server-side validation and context-specific escaping are still necessary when handling untrusted input.
Mental Model
Imagine a door with a strict guest list:
- Letters are allowed in.
- Numbers are allowed in.
- Ordinary spaces are allowed in.
- Every other character is turned away.
The regex is the bouncer. The [^...] pattern identifies everyone not on the guest list, and replace(..., "") removes them from the string.
Syntax and Examples
Use String.prototype.replace() with a negated character class and the global (g) flag.
const text = "Hello, World! #2025";
const cleaned = text.replace(/[^a-zA-Z0-9 ]/g, "");
console.log(cleaned); // "Hello World 2025"
How the pattern works:
[and]create a character class.a-zA-Z0-9lists allowed characters: lowercase letters, uppercase letters, digits, and a literal space.^at the beginning of the class negates it, so it matches characters outside that list.gmeans “globally”: replace every matching character, not only the first one.""is an empty string, so matched characters are removed.
Put it in a reusable function
function removeNonAlphanumeric(text) {
return text.replace(/[^a-zA-Z0-9 ]/g, "");
}
console.log(removeNonAlphanumeric("Order #42: Ready!"));
// "Order 42 Ready"
Keep all whitespace, not just ordinary spaces
If tabs and line breaks should remain too, use \s instead of a literal space:
const cleaned = text.replace(/[^a-zA-Z0-9\s]/g, "");
\s includes spaces, tabs, and line breaks. Use it only when that behavior is wanted.
Step by Step Execution
Consider this code:
const input = "Hi! Sam_7?";
const output = input.replace(/[^a-zA-Z0-9 ]/g, "");
console.log(output);
Step by step:
inputcontainsHi! Sam_7?.- The regex checks each character against the allowed set: letters, digits, and spaces.
Handiare letters, so they stay.!is not allowed, so it matches the regex and is removed.- The space is allowed, so it stays.
S,a, andmare allowed letters._is not allowed, so it is removed.7is an allowed digit.?is not allowed, so it is removed.- The resulting value is
"Hi Sam7".
The g flag is essential because both !, _, and ? must be removed.
Real World Use Cases
- Search input cleanup: Remove punctuation from a simple product-code or keyword search field.
- Username rules: Restrict a display name or generated identifier to a known set of characters.
- CSV and data imports: Clean inconsistent values before comparing or grouping them.
- File-label generation: Create safe, simple labels from user-provided titles.
- Log normalization: Remove symbols before producing a compact report or token.
Choose the allowed character set based on the actual requirement. For example, names often need apostrophes, hyphens, accented letters, or non-English writing systems, so an ASCII-only rule may be too restrictive.
Real Codebase Usage
In real projects, developers usually combine normalization, validation, and clear rules rather than applying one broad replacement everywhere.
Normalize then validate
function normalizeProductCode(value) {
const cleaned = value.replace(/[^a-zA-Z0-9 ]/g, "");
return cleaned.trim().replace(/ +/g, " ");
}
function isValidProductCode(value) {
return /^[a-zA-Z0-9 ]+$/.test(value);
}
Here:
trim()removes leading and trailing spaces.replace(/ +/g, " ")collapses repeated ordinary spaces.test()validates that the final value contains only allowed characters.
Use a guard clause for required input
function cleanLabel(value) {
if (typeof value !== "string") {
throw new TypeError("Label must be a string");
}
return value.replace(/[^a-zA-Z0-9 ]/g, "").trim();
}
A guard clause stops invalid input early, making the rest of the function easier to reason about.
For security-sensitive work, do not rely on character removal alone. Validate on the server, enforce authorization rules, and escape output for its destination (HTML, SQL parameters, URLs, and so on).
Common Mistakes
Forgetting the g flag
Without g, only the first disallowed character is removed.
const broken = "Hi! Sam?".replace(/[^a-zA-Z0-9 ]/, "");
console.log(broken); // "Hi Sam?"
Fix:
const fixed = "Hi! Sam?".replace(/[^a-zA-Z0-9 ]/g, "");
console.log(fixed); // "Hi Sam"
Forgetting the space in the allowed set
This removes spaces too:
"Hello, world!".replace(/[^a-zA-Z0-9]/g, "");
// "Helloworld"
Add a literal space before ] when spaces should remain:
"Hello, world!".replace(/[^a-zA-Z0-9 ]/g, "");
// "Hello world"
Using \s when only spaces are allowed
\s preserves tabs and newlines as well as spaces. If a single-line value must contain only ordinary spaces, use the literal space version.
Assuming ASCII covers every language
a-zA-Z does not match letters such as é, ñ, Ł, 你, or م. Use Unicode property escapes if the application should support international text.
const cleaned = "Café №42!".replace(/[^\p{L}\p{N} ]/gu, "");
console.log(cleaned); // "Café 42"
Treating cleanup as security protection
Removing symbols does not automatically prevent security issues. Use parameterized database queries, output escaping, and server-side validation appropriate to the context.
Comparisons
| Pattern | Keeps | Removes | Best use |
|---|---|---|---|
/[^a-zA-Z0-9 ]/g | ASCII letters, digits, ordinary spaces | Punctuation, symbols, tabs, non-ASCII letters | Simple English-only labels |
/[^a-zA-Z0-9\s]/g | ASCII letters, digits, all whitespace | Punctuation and symbols | Multi-line or tab-separated text |
/[^\p{L}\p{N} ]/gu | Letters and numbers from many writing systems, ordinary spaces | Punctuation and symbols | Internationalized text |
/[^a-zA-Z0-9_-]/g | ASCII letters, digits, underscores, hyphens | Other characters | Simple identifiers and slugs |
replace() transforms text by removing or changing matches. test() answers a different question: whether a string already follows the rule.
const isValid = /^[a-zA-Z0-9 ]+$/.test("Hello 42");
console.log(isValid); // true
Cheat Sheet
// Remove everything except ASCII letters, digits, and ordinary spaces
text.replace(/[^a-zA-Z0-9 ]/g, "");
// Preserve all whitespace: spaces, tabs, and line breaks
text.replace(/[^a-zA-Z0-9\s]/g, "");
// Preserve Unicode letters and numbers plus ordinary spaces
text.replace(/[^\p{L}\p{N} ]/gu, "");
// Check validity instead of modifying the text
/^[a-zA-Z0-9 ]+$/.test(text);
Rules to remember:
[^...]means “any character not listed here.”- Put
^immediately after[to negate a character class. - Use
gto replace every match. - A literal space permits only ordinary spaces.
\salso permits tabs and line breaks.+in a validation regex means “one or more”; use*if an empty string should be valid.
FAQ
How do I remove all special characters in JavaScript?
Use replace() with a negated character class:
text.replace(/[^a-zA-Z0-9 ]/g, "");
This preserves ASCII letters, digits, and spaces.
Why is the g flag needed in the regex?
Without g, JavaScript replaces only the first matching character. The g flag removes every disallowed character in the string.
Does this regex preserve spaces?
Yes, /[^a-zA-Z0-9 ]/g includes a literal space inside the allowed character class. It preserves ordinary spaces only.
How can I preserve tabs and newlines too?
Use \s:
text.replace(/[^a-zA-Z0-9\s]/g, "");
Does a-zA-Z support accented or non-English letters?
No. It supports only English ASCII letters. For broader language support, use Unicode property escapes such as /[^\p{L}\p{N} ]/gu.
How do I remove extra spaces after removing special characters?
Trim the ends and collapse repeated spaces:
text.replace(/[^a-zA-Z0-9 ]/g, "").trim().replace(/ +/g, " ");
Should I use this to secure user input?
No. It can enforce a formatting rule, but security also requires server-side validation, safe database queries, and correct output escaping.
Mini Project
Description
Build a small JavaScript utility that turns user-entered labels into clean ASCII labels. It demonstrates removing unwanted characters while preserving readable words and numbers.
Goal
Create a function that removes special characters, trims the result, and reduces repeated spaces to one space.
Requirements
- Accept a value that is a string.
- Keep only English letters, digits, and ordinary spaces.
- Remove punctuation and symbols.
- Remove spaces at the beginning and end.
- Replace multiple consecutive spaces with one space.
- Return the cleaned label.
Keep learning
Related questions
Are PDO Prepared Statements Enough to Prevent SQL Injection in PHP?
Learn how PDO prepared statements prevent SQL injection in PHP, what they protect, and the mistakes that still leave MySQL apps vulnerable.
Can You Bind an Array to an IN Clause in PHP PDO?
Learn how PDO handles placeholders in IN() clauses, why arrays cannot be bound directly, and the safe PHP pattern to build dynamic queries.
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.