Error Code: 3685. Illegal argument to a regular expression - mysql-8.0

I am trying to find an exact number in MySQL 8.0 using the below SQL statement
SELECT * FROM rulebook.node__body
WHERE body_value REGEXP "[[:<:]]DVP[[:>:]]";
when i am running the above SQL statement i am getting below error
Error Code: 3685. Illegal argument to a regular expression
could you please anyone tell me where i am making mistake.

This question will probably become more popular as adoption of MySQL 8.0 increases and previously-stored SQL queries using REGEXP start to break.
According to MySQL 8.0 Reference Manual / ... / Regular Expressions, "MySQL implements regular expression support using International Components for Unicode (ICU)."
According to MySQL 5.6 Reference Manual / ... / Regular Expressions, "MySQL uses Henry Spencer's implementation of regular expressions."
Therefore, since you are using MySQL 8.0, rather than using [[:<:]] and [[:>:]], you can now use \b. Your query might look like this:
SELECT *
FROM `rulebook`.`node__body`
WHERE `body_value` REGEXP "\\bDVP\\b"
;

In php() replace special symbol as four "backslashes + b"
Example:
$where = "regexp '[[:<:]](" . $custom_category . ")[[:>:]]'";
Replace with:
$where = "regexp '\\\\b(" . $custom_category . ")\\\\b'";
Parentheses don't matter...
If you wont replace recursive in your sites, use this script, for search and replace in all php files this pattern:
# find /var/www/user/data/www/site.com/ -type f -name '*.php' | xargs sed -i 's/\[\[\:[<|>]\:\]\]/\\\\\\\\b/g'

Your regex contains an invalid bracket. With the assumption that you are trying to find any row where body_value contains < and DVP and >, you can try:
SELECT * FROM rulebook.node__body
WHERE body_value REGEXP '.*<.*DVP.*>.*';

Related

Add more hash to existing hash script in multiple files

I've php script files that store password to MySQL using md5 hash
Here's some of existing query code in that php files
some query part....,MD5('$pass'),.....some query part
Some script has lowercase md5
some query part....,md5('$pass'),.....some query part
My goal is to add another hash to existing code, like, sh1
So the expected query script should be like this
some query part....,sh1(MD5('$pass')),.....some query part
at the end, the current md5 isn't matter if it's in lowercase or uppercase
I've tried to use sed to replace that files but no luck
sed -i 's/md5\(.*\)/sha1\(md5\(.*\)\)/gI' *.php
Is there anyone can help me?
Thanks
You may use
sed -i 's/\bmd5([^()]*)/sha1(&)/gI' *.php
The POSIX BRE expression matches:
\b - a word boundary
md5( - an md5( substring
[^()]* - 0 or more chars other than ( and )
) - a ) char.
The sha1(&) replacement pattern replaces the match woth sha1(, then the match value, and then ).
See the online demo:
s='some query part....,MD5('"'"'$pass'"'"'),.....some query part
some query part....,md5('"'"'$pass'"'"'),.....some query part'
sed 's/\bmd5([^()]*)/sha1(&)/gI' <<< "$s"
Output:
some query part....,sha1(MD5('$pass')),.....some query part
some query part....,sha1(md5('$pass')),.....some query part

Ruby or Bash or Grep regex is not working for '?' i.e. 0 or 1 occurrence of previous character

Linux Red Hat Enterprise Linux Server release 6.9 (Santiago)
Issue:
I have 2 Jenkins jobs and they both which calls another common/reusable downstream job (that uses a regex to pick its rpm). Actual code is written in Ruby (where I was using ::Dir.glob("<pattern>",'') and it didn't work for picking the correct rpm name (without giving me any error), but here I'm just focusing on the regex part.
In job1, in my workspace, I see myrpm.rpm and myrpm-extra.rpm.
In job2, in my workspace, I see myrpm-3.0.0.1027-2018_12_21_121519.noarch.rpm and myrpm-extra-3.0.0.1027-2018_12_21_121519.noarch.rpm rpms which I'm getting after downloading these files from Artifactory via some AQL.
Once rpms are downloaded from Aritfactory i.e. available in Jenkins workspace , then I use this common downstream job to pick a given rpm that I need by
using "${rpmname}*.rpm" regex.
The issue is, when I'm passing rpmname parameter value as "myrpm", the logic is picking myrpm-extra.rpm (in Job1) or myrpm-extra-3.0.0.1027-2018_12_21_121519.noarch.rpm (Job2) instead of the correct one (non extra one), as - character's order comes first due to ASCII sequence.
I tested the regex and seeing why in the last command I didn't see expected output. Isn't 1? in the regex going to give us any lines which has arun with either 0 or 1 occurrence of character 1?
[giga#linux-server giga]# echo -e "arun\narun1\narun2\narun11" |grep "arun"
arun
arun1
arun2
arun11
[giga#linux-server giga]#
[giga#linux-server giga]# echo -e "arun\narun1\narun2\narun11" |grep "arun1"
arun1
arun11
[giga#linux-server giga]#
[giga#linux-server giga]# echo -e "arun\narun1\narun2\narun11" |grep "arun1?"
[giga#linux-server giga]#
Questions:
1. Why this works if I use egrep?
2. Why it didn't work with grep, while grep man page / examples tells it supports it?
3. What regex can I use so that if I pass myrpm as the job parameter's value, then it works in both Job1 and Job2 where rpm filename contains either the short and full rpm name.
Here: https://www.cyberciti.biz/faq/grep-regular-expressions/ (search for grep Regular Expression Operator) and
man grep shows:
Repetition
A regular expression may be followed by one of several repetition operators:
---------------------------------------------------------------
? The preceding item is optional and matched at most once.
---------------------------------------------------------------
* The preceding item will be matched zero or more times.
+ The preceding item will be matched one or more times.
{n} The preceding item is matched exactly n times.
{n,} The preceding item is matched n or more times.
{,m} The preceding item is matched at most m times. This is a GNU extension.
{n,m} The preceding item is matched at least n times, but not more than m times.
egrep is the same as grep -E, in your case, the regex used, need -E or -P to support ?.
Search for different regex support please. There're POSIX, Extended, and Perl etc.
Resources:
POSIX Basic and Extended Regular Expressions
Perl regular expressions
Regular expression
Final Solution:
Used this regex pattern: ${package_name}(?:-[0-9]*)?\..*rpm, example of code (in Ruby) is shown below.
In Ruby: after you change to the directory where the rpms existed, I got this line to find the correct rpm name. NOTE: In Ruby, ::Dir.glob("<pattern>",..) is not a real REGEX pattern, it's just a SHELL glob pattern.
wildcard = "#{new_resource.session['package_name']}(?:-[0-9]*)?\..*#{ext_type}"
rpmfullname = Dir["#{new_resource.session['package_name']}*.#{ext_type}"].select { |f| f =~ /#{wildcard}/ }.sort.first
This website greatly helped.
https://rubular.com/
with example pattern being myrpm(?:-[0-9]*)?\..*rpm:
and test cases strings as:
myrpm.rpm
myrpm-extra.rpm
myrpm-1.0.0_112233.noarch.rpm
myrpm-11.0.0_112233.noarch.rpm
myrpm-111.0.0_112233.noarch.rpm
myrpm-1.0_112233.noarch.rpm
myrpm-extra-1.0.0_112233.noarch.rpm
foo.yum
berayan.rpm
arun.yum
Toni.rpm
myrpm-1.0.0_112233.rpm

How to use a regular expression to get the following pattern?

Hello I have the following text:
some text,+
this field is another parameter
this is the final of the field
t10681374flp
t10681375flp
I would like to match the following two lines:
t10681374flp
t10681375flp
the rule is that these words begin with 't' and end with 'p',
I tried:
grep -e t*p testing
however I got:
this field is another parameter
t10681374flp
t10681375flp
So I really would like to appreciate support to overcome this task,
Using grep, to avoid matching strange lines and the perfect match, the code below
grep "^t[0-9]*flp$" testing
This matches the below lines,
t10681374flp
t10681375flp
This doesn't match the lines as below,
this field is another parameter
these dont grep
Hope you get resolved..
Following should do the work:
grep ^t.*p$ testing
^ indicates begining of the line, .* indicates any character
and $ indicates end of line.

grep wildcards issue ubuntu

I have an input file named test which looks like this
leonid sergeevich vinogradov
ilya alexandrovich svintsov
and when I use grep like this grep 'leonid*vinogradov' test it says nothing, but when I type grep 'leonid.*vinogradov' test it gives me the first string. What's the difference between * and .*? Because I see no difference between any number of any characters and any character followed by any number of any characters.
I use ubuntu 14.04.3.
* doesn't match any number of characters, like in a file glob. It is an operator, which indicates 0 or more matches of the previous character. The regular expression leonid*vinogradov would require a v to appear immediately after 0 or more ds. The . is the regular expression metacharcter representing any single character, so .* matches 0 or more arbitrary characters.
grep uses regex and .* matches 0 or more of any characters.
Where as 'leonid*vinogradov' is also evaluated as regex and it means leoni followed by 0 or more of letter d hence your match fails.
It's Regular Expression grep uses, short as regexp, not wildcards you thought. In this case, "." means any character, "" means any number of (include zero) the previous character, so "." means anything here.
Check the link, or google it, it's a powerful tool you'll find worth to knew.

How to decrement (subtract) number in file with sed

I've got some source code like the following where I call a function in C:
void myFunction (
&((int) table[1, 0]),
&((int) table[2, 0]),
&((int) table[3, 0])
);
...the only problem is that the function has >300 parameters (it's an auto-generated wrapper for initialising and calling a whole module; it was given to me and I cannot change it). And as you can see: I began accessing the array with a 1 instead of a 0... Great times, modifying all the 300 parameters, i.e. decrasing 300 x the x-coordinate of the array, by hand.
The solution I am looking for is how I could force sed to to do the work for me ;)
EDIT: Please note that the syntax above for accessing a two-dimensional array in C is wrong anyway! Of course it should be [1][0]... (so don't just copy-and-paste ;))
Basically, the command I came up with, was the following:
sed -r 's/(.*)(table\[)([0-9]+)(,)(.*)/echo "\1\2$((\3-1))\4\5"/ge' inputfile.c > outputfile.c
Well, this does not look very intuitive on the first sight - and I was missing good explanations for nearly every example I found.
So I will try to give a detailed explanation on this:
sed
--> basic command
-r
--> most examples you find are using -e; however, the -r parameter (only works with GNU sed) enables extended regular expressions and brings support for the + in a regex. It basically means "one or more matches".
's/input/output/ge'
--> this is the basic replacement syntax. It basically means "replace 'input' by 'output'". The /g is a "global" flag, i.e. sed will replace all occurences and not only the first one. You can add an additional e to execute the result in the bash. This is what we want to do here to handle the calculation.
(.*)
--> this matches "everthing" from the last match to the next match
(table\[)
--> the \ is to escape the bracket. This part of the expression will match Strings like table[
([0-9]+)
--> this one matches numbers with at least one digit, however, it can also match higher numbers with more than only one digit.
(,)
--> this simply matches the comma ,
(.*)
--> and again: the rest of the line
And now the interesting part:
echo "\1\2$((\3-1))\4\5"
the echo is a bash command
the \n (you can use every value from \1 up to \9) is some kind of "variable" for the inputs: \1 will contain the first match, \2 the seconds match, ... --> this helps you to preserve parts of the input string
the $((1+1)) is a simple bash syntax to calculate the value of the term inside the double brackets (in the complete sed command above, the \3 will of course be automatically replaced by the 3rd match, i.e. the 1st part inside the brackets to access the table's cells)
please note that we use quotation marks around the echo content to also be able to process lines with characters like & which would otherwise not work
The already mentioned e of \ge at the end will trigger the execution of the result in the bash. E.g. the first two lines of the example source code in the question would produce the following bash statements:
echo "void myFunction ("
echo " &((int) table[$((1-1)), 0]),"
which is being executed and results in the following output:
void myFunction (
&((int) table[0, 0]),
...which is exatcly what I wanted :)
BTW:
text > output.c
is simple bash syntax to output text (or in this case the sed-processed source code) to a file called output.c.
Good links about this topic are:
sed basics
regular expressions basics
Ahh and one more thing: You can also use sed in the git-Bash on Windows - if you are "forced" to use Windows at work like me ;)
PS: In the meantime I could have easily done this by hand but using sed was a lot more fun ;)
Here's another way you could do it, using Perl:
perl -pe 's/(table\[)(\d+)(,)/$1.($2-1).$3/e' file.c
This uses the e modifier to execute an expression in the replacement. The capture groups are concatenated together but the middle group has 1 subtracted from its value.
This will output to standard output so you can check that it does what you want. When you're happy, you can add the -i switch to overwrite the original file.

Resources