#1139 - Got error 'repetition-operator operand invalid' from regexp - mysql

I'm having trouble using a regular expression to select some results from my MySQL table.
I'm using this query
SELECT text
FROM `articles`
WHERE content REGEXP '.*<img.*?src=\"http://www'
ORDER BY date DESC
And it says
#1139 - Got error 'repetition-operator operand invalid' from regexp
I tested the regex with Notepad++ and it works, why MySQL is giving me this error and how can i fix it?

According to the MySQL manual
MySQL uses Henry Spencer's implementation of regular expressions, which is aimed at conformance with POSIX 1003.2
POSIX regexes don't support using the question mark ? as a non-greedy (lazy) modifier to the star and plus quantifiers like PCRE (Perl Compatible Regular Expressions). This means you can't use +? and *?
It looks like you'll just have to use the greedy version, which should still work. To avoid the matching of things like <img style="/*some style*/" src="a.png"> <script src="www.example.com/js/abc.js">, you can use a negated character class:
'<img[^>]*src="http://www'
Note: The " doesn't have to escaped and the .* at the beginning is implied.

You can try,
SELECT
text
,
IF (content LIKE '%<img src="http://%', text , content LIKE '%<img style=%')
as imageText
FROM articles ORDER BY date DESC
This will Check first for where content has <img src="http:// if it can't find then it will look for <img style= instead.
Hope it Helps.
Check Fiddle: http://sqlfiddle.com/#!2/6a2f0/13/0

Related

Types of Wildcards in MySql

My query:
Select * From tableName Where columnName Like "[PST]%"
is not giving the expected result.
Why does this wildcard not work in MySql?
If you want to filter on strings that contain any 'P', 'S', or 'T', then you can use a regex:
where col rlike '[PST]'
If you want strings that contain substring 'PST', then no need for square brackets - and like is enough:
where col like '%PST%'
If you want the matching character(s) at the start of the string, then the regex solution looks like:
where col rlike '^PST'
And the like option would be:
where col like 'PST%'
MySQL's LIKE syntax is documented here: https://dev.mysql.com/doc/refman/8.0/en/pattern-matching.html
Standard SQL from decades ago defined only two wildcards: % and _. These are the only wildcards an SQL product needs to support if they want to say they are SQL compliant and support the LIKE predicate.
% matches zero or more of any characters. It's analogous to .* in regular expressions.
_ matches exactly one of any character. It's analogous to . in regular expressions.
Also if you want to match a literal '%' or '_', you need to escape it, i.e. put a backslash before it:
WHERE title LIKE 'The 7\% Solution'
Microsoft SQL Server's LIKE syntax is documented here: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/like-transact-sql?view=sql-server-ver15
They support % and _ wildcards, and the \ escape character, but they extend standard SQL with two other forms:
[a-z] matches one character, but only characters in the range inside the brackets. This is similar in regular expressions. The - is a range operator, unless it appears at the start or end of the string inside the brackets.
[^a-z] matches one character, which must not be one of the characters in the range inside the brackets. Also the same in regular expressions.
These are not standard forms of wildcards for the LIKE predicate, and other brands of SQL database don't support them.
Later versions of the SQL standard introduced a new predicate SIMILAR TO which supports much richer patterns and wildcards, since the right-side operand is a string which contains a regular expression. But since this predicate was introduced in a later edition of the SQL standard, some implementations had already developed their own solution that was almost the same.
MySQL called the operator REGEXP and RLIKE is a synonym (https://dev.mysql.com/doc/refman/8.0/en/regexp.html).
It was requested in https://bugs.mysql.com/bug.php?id=746 to support SIMILAR TO syntax to help MySQL comply with the SQL standard, but the request was turned down, because it had subtly different behavior to the existing REGEXP/RLIKE operator.
Microsoft SQL Server has partial support of regular expression wildcards in the LIKE operator, and also a dbo.RegexMatch() function.
SQLite has a GLOB operator, and so on.
Thanks everyone!
For specific this question, we need to use regexp
Select * From tableName Where ColumnName Regexp "^[PST]";
For more detail over Regular Expression i.e Regexp :
https://www.youtube.com/watch?v=KoltE-JUY0c

Search Credit Cards in MySQL

I'm trying to find plain credit card number in my database.
I want to make sure that a text content does not contain credit cards. As some client type their credit cards when they file report
I tried :
SELECT * FROM reports WHERE content RLIKE '\b(?:\d[ -]*?){13,16}\b';
It gave me this error
ERROR 1139 (42000): Got error 'repetition-operator operand invalid' from regexp
I need some help please.
Thanks
MySQL regular expression syntax doesn't use \b for word boundaries, it uses[[:<:]] and [[:>:]]. It doesn't use \d for digits, it uses [[:digit:]]. It also doesn't have ?: prefix in groups -- they're not needed because it doesn't have back-references, so there's no difference between capturing and non-capturing groups.
But the reason for your error message is that it doesn't have non-greedy quantifiers like *?.
Try this:
SELECT *
FROM reports
WHERE content RLIKE '[[:<:]]([[:digit:]][- ]?){13,16}[[:>:]]'
This matches a word beginning, 13-16 digits with a possible separator after each, followed by a word end.

Got error 'repetition-operator operand invalid' from regexp in Mysql

I'm having trouble using a regular expression to select some results from my MySQL table.
I'm using this query
select id, orderid, `desc`
from paymentlog
where `desc` REGEXP '[^.]*(?:_SVD(\d*))[[:>:]]'
And it says
#1139 - Got error 'repetition-operator operand invalid' from regexp
This regex works well with my other editors/validators.
Any advice much appreciated.
MySQL regular expressions don't support the full syntax of Perl-Compatible Regular Expressions.
The (?:) grouping syntax is not supported in MySQL. That syntax is for grouping without backreferences. But it doesn't matter in MySQL, since MySQL doesn't support backreferences anyway (related to this, MySQL has no regular expression substitution function).
In fact, you don't need any parens in your example.
As #ruakh says, \d isn't a code to match digits. You need to use POSIX character classes in MySQL.
So your expression should look like this:
where `desc` REGEXP '_SVD[:digit:]*[[:>:]]'
I also left out your [^.]* since it doesn't matter in this expression. You aren't matching the beginning of the string, so zero characters of that class would succeed the match even if you did have a . before the rest of the pattern. You might mean to match only if you have non-dot characters from the start of the string, like this:
where `desc` REGEXP '^[^.]*_SVD[:digit:]*[[:>:]]'

Match optional end of line

Hey I want to use a regular expression in MySQL to match rows.
It needs to match rows where a the pattern ends with anything that's not a digit or the end of the line.
This pattern works in Ruby /download:223(?:[\D]|$)/
In MySQL it doesn't match. I'm guessing it doesn't allow for optional matching of eol.
SELECT id FROM stories WHERE body REGEXP 'download:223(?:[\D]|$)'
I need to match the following (quotes just for clarity):
"download:223"
"download:223*"
"download:223 something"
"download:223 more text"
But NOT the following (again quotes just for clarity):
"download:2234"
"download:2234 more text"
"download:2234*"
"download:2234* even more"
Thanks!
This regex should work for you:
"download:223([^0-9]|$)"
MySQL regex engine doesn't support \D, \d etc.
Non-capturing groups are not supported in MySQL regexes. The rest should be fine. It definitely supports $ matching the end of string. Also, \D is not supported, but you can use [^0-9]
Try this:
SELECT id FROM stories WHERE body REGEXP 'download:223([^0-9]|$)'
MySQL groups don't capture, so supporting non-capturing groups is unnecessary.
Reference source:
Using Non-Capturing Groups in MySQL REGEXP

How do I search and replace using regex in MySQL?

I'm trying to update a field which contains HTML and I want to find all the rows that have forms in them and remove the form tags and anything in between them, however I'm running into problems with my select and the regex.
SELECT * FROM db.table WHERE body REGEXP "<form[^>].+?>.+?</form>";
and the error I get says:
'repetition-operator operand invalid' from regexp.
I was hoping to make that SELECT into a subselect for an update query but I'm stuck at this point.
I think your problem is in your form expression. Try the following:
"<form[^>]*>.+?</form>"
Remember that MySQL supports a limited set of regular expression matching and testing.
See this document.