MySQL REGEXP tests whether text matches a regular-expression pattern. It is useful when LIKE wildcards such as % and _ are not expressive enough.
SELECT id,
name
FROM student
WHERE name REGEXP '^A'
ORDER BY id;
The pattern ^A means "starts with A".
^ for the beginning and $ for the end when the position matters.The old version of this page described LIKE as matching only the entire value. More precisely, LIKE matches the whole string against a wildcard pattern, while REGEXP searches for a regular-expression match unless anchors restrict it.
SELECT 'plus2net.com' LIKE '2n' AS like_result;
Result: 0
SELECT 'plus2net.com' REGEXP '2n' AS regexp_result;
Result: 1, because the sequence 2n occurs inside the string.
| Pattern | Meaning |
|---|---|
. | Matches one character. |
[abc] | Matches one character from the listed set. |
[a-z] | Matches one character in the specified range. |
[0-9] | Matches one digit in the specified range. |
* | Matches zero or more repetitions of the preceding expression. |
+ | Matches one or more repetitions of the preceding expression. |
? | Matches zero or one occurrence of the preceding expression. |
^ | Anchors the match at the start of the string. |
$ | Anchors the match at the end of the string. |
{n} | Matches exactly n repetitions. |
| | Alternation: matches either expression. |
(...) | Groups part of a regular expression. |
? means zero or one occurrence, not zero or more. Zero or more is *.A dot matches one character:
SELECT 'cat' REGEXP 'c.t' AS matched;
The result is true because the dot matches a.
To match an entire three-character name, combine dots with start and end anchors:
SELECT id,
name
FROM student
WHERE name REGEXP '^...$';
| id | name | class | mark | sex |
|---|---|---|---|---|
| 13 | Kty | Seven | 88 | female |
Square brackets match one character from a set or range.
SELECT id,
name,
class,
mark,
sex
FROM student
WHERE name REGEXP '^[AB]'
ORDER BY id;
| id | name | class | mark | sex |
|---|---|---|---|---|
| 3 | Arnold | Three | 55 | male |
| 6 | Alex John | Four | 55 | male |
| 8 | Asruid | Five | 85 | male |
| 10 | Big John | Four | 55 | female |
| 14 | Bigy | Seven | 88 | female |
| 21 | Babby John | Four | 69 | female |
| 27 | Big Nose | Three | 81 | female |
| 32 | Binn Rott | Seven | 90 | female |
SELECT id,
name
FROM student
WHERE name REGEXP '^[A-F]';
* means zero or more repetitions of the preceding expression.
SELECT 'ac' REGEXP 'ab*c' AS zero_b,
'abc' REGEXP 'ab*c' AS one_b,
'abbbc' REGEXP 'ab*c' AS many_b;
All three expressions match because the pattern accepts zero, one, or many b characters.
name REGEXP 'b*' returns virtually every non-NULL string because zero occurrences of b are allowed. It is technically explainable but a poor search example. Use surrounding characters or anchors when you want a meaningful restriction.+ requires at least one occurrence of the preceding expression.
SELECT id,
name,
class,
mark,
sex
FROM student
WHERE name REGEXP 'c+'
ORDER BY id;
| id | name | class | mark | sex |
|---|---|---|---|---|
| 12 | Recky | Six | 94 | female |
| 20 | Jackly | Nine | 65 | female |
| 26 | Crelea | Seven | 79 | male |
Case sensitivity depends on the comparison rules discussed below.
? makes the preceding expression optional.
SELECT 'color' REGEXP 'colou?r' AS color_match,
'colour' REGEXP 'colou?r' AS colour_match;
Both values match because u? allows zero or one u.
c? can match an empty position in almost any string because the c is optional. That is why the old name REGEXP 'c?' example returned all rows.Return names that start with A:
SELECT id,
name,
class,
mark,
sex
FROM student
WHERE name REGEXP '^A'
ORDER BY id;
| id | name | class | mark | sex |
|---|---|---|---|---|
| 3 | Arnold | Three | 55 | male |
| 6 | Alex John | Four | 55 | male |
| 8 | Asruid | Five | 85 | male |
Return names ending with a:
SELECT id,
name,
class,
mark,
sex
FROM student
WHERE name REGEXP 'a$'
ORDER BY id;
| id | name | class | mark | sex |
|---|---|---|---|---|
| 26 | Crelea | Seven | 79 | male |
{n} requires exactly n repetitions of the preceding expression.
SELECT 'aaaa' REGEXP '^a{4}$' AS matched;
This matches exactly four a characters.
Four-character names:
SELECT id,
name,
class,
mark,
sex
FROM student
WHERE name REGEXP '^.{4}$';
| id | name | class | mark | sex |
|---|---|---|---|---|
| 14 | Bigy | Seven | 88 | female |
The start and end anchors ensure that all four characters make up the complete string.
NOT REGEXP returns rows whose value does not match the pattern.
SELECT id,
name,
class,
mark,
sex
FROM student
WHERE name NOT REGEXP '^[ABGTRJKM]'
ORDER BY id;
The original sample returned names beginning outside that listed group of letters.
NOT REGEXP does not return NULL values, because the REGEXP comparison itself is NULL for a NULL input. Add OR name IS NULL if NULL rows should also be included.The pipe character means "either pattern".
SELECT id,
name
FROM student
WHERE name REGEXP 'John|Alex'
ORDER BY id;
This matches names containing either John or Alex.
Parentheses group part of a pattern, which is useful with repetition or alternation.
SELECT 'abab' REGEXP '^(ab){2}$' AS matched;
The grouped expression (ab) is repeated exactly twice.
REGEXP case behavior depends on the character set and collation of the expression. With a case-insensitive collation, a lowercase pattern can match uppercase text.
The old page used:
SELECT id,
name
FROM student
WHERE name REGEXP BINARY '^[Ab]';
Using BINARY can force a binary/case-sensitive comparison, but it is not the only modern option.
REGEXP_LIKE() provides an explicit match-type argument, including 'c' for case-sensitive matching and 'i' for case-insensitive matching.MySQL 8 provides REGEXP_LIKE() as a function form of regular-expression testing.
SELECT id,
name
FROM student
WHERE REGEXP_LIKE(
name,
'^[Ab]',
'c'
)
ORDER BY id;
SELECT id,
name
FROM student
WHERE REGEXP_LIKE(
name,
'^[ab]',
'i'
)
ORDER BY id;
Use the operator form when it is sufficient; use the function form when explicit match options make the query clearer.
If the text expression is NULL, REGEXP does not return true or false; the comparison result is NULL.
SELECT NULL REGEXP 'A' AS result;
Therefore:
WHERE name NOT REGEXP '^A'
does not automatically include rows where name is NULL.
If NULL must be included:
WHERE name NOT REGEXP '^A'
OR name IS NULL
See SQL NULL values.
When the pattern comes from the application, bind it as a value:
<?php
$pattern='^[AB]';
$sql="SELECT id, name, class, mark
FROM student
WHERE name REGEXP :pattern
ORDER BY id";
$stmt=$dbo->prepare($sql);
$stmt->bindValue(
':pattern',
$pattern,
PDO::PARAM_STR
);
$stmt->execute();
foreach($stmt->fetchAll(PDO::FETCH_ASSOC) as $row){
echo '<p>'
.htmlspecialchars(
$row['name'],
ENT_QUOTES,
'Windows-1252'
)
.'</p>';
}
A prepared statement protects the SQL value boundary, but it does not make an arbitrary user-supplied regular expression inexpensive or suitable. If users can submit patterns, validate length and application-specific complexity limits.
^ABC communicates more restriction than an unanchored pattern, but do not assume every REGEXP pattern will use a normal B-tree index efficiently.EXPLAIN and measure the actual query.If the requirement is simply "starts with John", this is often clearer:
SELECT id,
name
FROM student
WHERE name LIKE 'John%';
Use REGEXP when the search genuinely requires richer pattern logic.
* means zero or more. ? means zero or one.
Patterns such as b* and c? can succeed without consuming a character, so they may match nearly every non-NULL value.
Without anchors, REGEXP normally searches for the pattern anywhere in the value.
Case behavior depends on collation and, with REGEXP_LIKE(), explicit match options.
BINARY is one option, but MySQL 8 also provides explicit case control through REGEXP_LIKE().
NULL comparisons remain NULL. Add an explicit OR column IS NULL when required.
Use = for exact equality and LIKE for simple wildcard patterns. Choose REGEXP only when regular-expression features are needed.
Prepared statements prevent SQL injection through the value boundary, but application-level limits are still useful to prevent overly expensive searches.
Download SQL dump of the student table
REGEXP tests whether a text value matches a regular-expression pattern.
LIKE uses simple wildcard patterns for the complete string, while REGEXP supports anchors, repetition, character classes, alternation, grouping, and other regular-expression features.
^ anchors the pattern at the start of the string and $ anchors it at the end.
* means zero or more repetitions of the previous expression. ? means zero or one occurrence.
It depends on the collation of the expression. MySQL 8 REGEXP_LIKE() also provides explicit case-sensitive and case-insensitive match options.
Use NOT REGEXP. Add an explicit IS NULL condition if NULL values should also be returned.
No. Use equality or LIKE when those simpler operations satisfy the requirement, and use REGEXP for patterns that need regular-expression features.
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.