Search Credit Cards in MySQL - 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.

Related

MySQL throwing error "Error Code: 3685. Illegal argument to a regular expression" when calculating accurate occurrence of phrase(s) inside column

As I mentioned in the Q-title, as now the MySQL has been heavily upgraded to version 8, which expectedly provides much new features including shortened characters for Word Boundary matching, calculating exact occurrence of phrase(s) inside column where one row-column(cell) may contain multiple occurrences of searched term/phrase must become easier to achieve.
Yet when I am using this proper looking query to count the exact occurrence of string it throws the below given error:
SELECT
ROUND((LENGTH(`column_name`) - LENGTH(REGEXP_REPLACE(`column_name`,
"^[[:<:]]Home Depot[[:>:]]$",
''))) / LENGTH('Home Depot')) AS `found`
FROM
<DB>.<TableName>;
Where if there are 2 rows as below:
Home Depot is a good one but Home Depot
Home Depot is a bad one
Then it must return found(count of total occurrence) as 3 instead of just no. of rows 2.
But on the contrary it throws error: Error Code: 3685. Illegal argument to a regular expression.
And if I use \\b instead of the [[:<:]], then it gives too many rows of the order of 1000000 which is ofcourse the wrong count as there aren't that much rows in the entire table, so it's just the Regex engine messing up.
Anyone care to help out achieve what I want ?
You need to change the word boundaries to \\b. And to match Home Depot anywhere in the string, you must remove the ^ and $ anchors. Finally, to get the total number of replacements, you have to use SUM() to add up the values from each row.
I don't think you need to use ROUND() since the numerator should always be an exact multiple of the denominator.
Putting it all together:
SELECT SUM((LENGTH(`column_name`) -
LENGTH(REGEXP_REPLACE(`column_name`, "\\bHome Depot\\b", '')))
/ LENGTH('Home Depot')) AS found
FROM db.tablename

digit character class in regexp doesn't work in MySQL for me

The following query
SELECT "T2N1M0" REGEXP "^T[:digit:].*";
returns single row with 0 for me.
I would expect it return 1.
What I am doing wrong?
You are missing one level of square brackets []:
SELECT "T2N1M0" REGEXP "^T[[:digit:]].*";
You should have gotten this error message that hints at the problem:
Got error 'POSIX named classes are supported only within a class at offset ' from regexp
More one the syntax for regular expressions are given by the manual page 13.5.2 Regular Expressions.

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:]*[[:>:]]'

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

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

mySQL Regexp with square brackets

I am trying to match strings like '[sometext<someothertext>]' (i.e., left square bracket, text, left angle bracket, text, right angle bracket, right square bracket) within a column in mySQL. Originally I used the following query (notice that since regex queries are escaped twice in mySQL, you must use two backslashes where you would normally use one):
SELECT * FROM message WHERE msgtext REGEXP '\\[(.+)?<(.+)?>\\]'
This query received no errors, but it returned things I didn't want. Instead of the (.+), I wanted [^\]] (match everything except a right square bracket). When I changed the query, I got the following error: "Got error 'repetition-operator operand invalid' from regexp"
After reading through the mySQL documentation here, it states "To include a literal ] character, it must immediately follow the opening bracket [." Since I want "^\]" instead of "]", is this even possible since the bracket can't be the first character after the opening bracket? Below are some of the queries I have tried which get the same error listed above:
SELECT * FROM message WHERE msgtext REGEXP '\\[([^\\]]+?)<([^\\]]+?)>\\]'
SELECT * FROM message WHERE msgtext REGEXP '\\[[^\\]]+?<[^\\]]+?>\\]'
SELECT * FROM message WHERE msgtext REGEXP '\\[[^[.right-square-bracket.]]]+?<[^[.right-square-bracket.]]]+?>\\]'
UPDATE:
The following query runs without errors, but does not return any rows even though I know there are columns which match what I am looking for (based on my original query at the top):
SELECT * FROM message WHERE msgtext REGEXP '\\[([^\\]]+)?<([^\\]]+)?>\\]'
This works for me:
SELECT '[sometext<someothertext>]' REGEXP '\\[([^[.right-square-bracket.]]+)?<([^[.right-square-bracket.]]+)?>\\]$';
Your final regex looks correct and works in Firefox/JS once the slashes are unescaped. Doesn't look like MySQL supports capture groups natively though... Maybe that's the problem.
Perhaps this would useful: http://mysqludf.com/lib_mysqludf_preg/
Also, you might try a * instead of +? for your negated right squares.
* means 0 or more repetitions (greedy)
+? means 1 or more repetitions (lazy)