4

I tried matching keywords with REGEXP in MySQL as following:

-- Match "fitt*", the asterisk "*" is expected to be matched as-is

> select 'aaaa fitt* bbb' regexp '[[:<:]]fitt\*[[:>:]]'; -- return 1, ok
> select 'aaaa fitttttt* bbb' regexp '[[:<:]]fitt\*[[:>:]]'; -- return 1 as well, but should return 0

> select 'aaaa fitt* bbb' regexp '[[:<:]]fitt\\*[[:>:]]'; -- return 0, failed

How to escape the asterisk (*) in order to exactly match the character *?

3
  • 1
    The problem isn't with the asterisk, it's with [[:>:]]. That only matches at a word boundary, but there's no word boundary between * and space because * isn't a word character. Commented Jul 1, 2016 at 3:10
  • @Barmar Thanks. But how to match the word fitt* with REGEXP? Commented Jul 1, 2016 at 3:13
  • I changed the title based on the debate between @Barmar and myself. Commented Jul 8, 2016 at 18:03

2 Answers 2

5

\\* is the correct way to match the asterisk. But [[:>:]] won't match after it, because that only matches between a word character and a non-word character, and * is not a word character. Instead, you need to match a non-word character there explicitly. You also need an alternative for the end of line, since that's the other type of word boundary.

> select 'aaaa fitt* bbb' regexp '[[:<:]]fitt\\*([^[:alnum:]]|$)'; -- returns 1
> select 'aaaa fitttttt* bbb' regexp '[[:<:]]fitt\\*([^[:alnum:]]|$)'; -- returns 0

Another way to match the asterisk explicitly is by putting it in a character class.

> select 'aaaa fitt* bbb' regexp '[[:<:]]fitt[*]([^[:alnum:]]|$)'; -- returns 1
> select 'aaaa fitttttt* bbb' regexp '[[:<:]]fitt[*]([^[:alnum:]]|$)'; -- returns 0
Sign up to request clarification or add additional context in comments.

8 Comments

No. \\* means zero or more backslashes. Your test happens to work because it found zero backslashes, then a *, which is not an 'alnum'.
@RickJames The first backslash escapes the second backslash in the string. That resulting backslash escapes the * in the regexp.
If I put a backslash in the string being tested, it doesn't match it.
Was the backslash in the string escaped? SELECT 'a\b' REGEXP 'a.b', 'a\\b' REGEXP 'a.b'; --> 0, 1.
@RickJames select 'aaaa fitt\\* bbb' regexp '[[:<:]]fitt\\*([^[:alnum:]]|$)'; -> 0`
|
1

There could be 3 problems:

Item 1: The answer to the title question is either of these:

\\*  (in the regexp)
[*]

Item 2: \\\\* may be needed if you are coming from some client that first unescapes the backslash before feeding it to MySQL, which still needs a backslash. However, as written (without any client code), \\\\* is treated as zero or more backslashes.

Item 3: @Barmar's answer focused on why [[:>:]] is incorrect.

3 Comments

\\* is needed if you're writing the string literally in the query, since MySQL itself first unescapes the backslash.
And if you're doing it in a client programming language that also unescapes, you need to double it again, e.g. $sql = "SELECT 'aaaa fitt* bbb' regexp '[[:<:]]fitt\\\\*([^[:alnum:]]|$)'"; in PHP.
@Barmar and Zelong -- I'm testing in the mysql commandline tool; what are you testing in?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.