using a regex to remove invalid values from image - mysql

working on a code where we are storing images but some images ending with weird characters
like , %2C -x1 to x10 etc or more but always end wih a .jpg
how can i regex to replace the image name to be a valid name
here is an example of what i have
PCpaste_10_g,-X1,-X2,-X3
SNBar_NEW,-X1
they can go till -X10
so i want to have regex to remove ,and everything afterwards it
i tried using replace but that only works for one item at a time

If your data is consistent with the string before the first comma that need to be taken, then you can try with SUBSTRING_INDEX;
Let's use this as you sample table & using your sample data:
CREATE TABLE mytable (
val VARCHAR(255));
INSERT INTO mytable VALUES
('PCpaste_10_g,-X1,-X2,-X3.jpg'),
('SNBar_NEW,-X1.jpg');
val
PCpaste_10_g,-X1,-X2,-X3.jpg
SNBar_NEW,-X1.jpg
Then first you extract the first string before comma occurrence:
SELECT SUBSTRING_INDEX(val,',',1) extracted
FROM mytable
returns
extracted
PCpaste_10_g
SNBar_NEW
Then to add back .jpg:
SELECT CONCAT(SUBSTRING_INDEX(val,',',1),'.jpg') extracted_combined
FROM mytable
IF your image extension is not consistently .jpg, you can do another SUBSTRING_INDEX() to get the extension then CONCAT() them:
SELECT CONCAT(SUBSTRING_INDEX(val,',',1) ,'.',
SUBSTRING_INDEX(val,'.',-1)) Extracted_combined
FROM mytable;
Demo fiddle

You can use LOCATE to find the first occurrence of "," in the field and LEFT to grab everything up to the first "," -
SET #value := 'PCpaste_10_g,-X1,-X2,-X3';
SELECT CONCAT(LEFT(#value, LOCATE(',', #value) - 1), '.jpg');
or for your update -
UPDATE <table>
SET image_name = CONCAT(LEFT(image_name, LOCATE(',', image_name) - 1), '.jpg')
WHERE image_name LIKE '%,%';
or to handle your %2C at the same time -
UPDATE <table>
SET image_name = CASE
WHEN image_name LIKE '%,%'
THEN CONCAT(LEFT(image_name, LOCATE(',', image_name) - 1), '.jpg')
WHEN image_name LIKE '%\%2C%'
THEN CONCAT(LEFT(image_name, LOCATE('%2C', image_name) - 1), '.jpg')
END
WHERE image_name LIKE '%,%'
OR image_name LIKE '%\%2C%';

Related

Removing everything after a string in mysql

I have a bunch of image file names that i uploaded to wordpress and want to change the file names using sql in phpmyadmin. The files are as such:
text-text-text-328x328.jpg
text-text-590x236.jpg
text-text-text-text-150x150.jpg
text-569x348.jpg
tex-text-text.jpg
So i want to remove the file in the title. The only footprint i can thing of is removing string after - plus a number
I know how to remove everything after - :
UPDATE MyTable
SET MyText = LEFT(MyText, CHARINDEX('-', MyText) - 1)
WHERE CHARINDEX(';', MyText) > 0
Just not sure how to remove everything after - and a number.
Thanks!
SELECT
name,
concat(
substr(name, 1, length(name) - length(substring_index(name,'-',-1)) - 1),
'.',
substring_index(name, '.', -1)
) as newname
FROM 0_a

MySQL: How do I search and replace chars at the beginning of a string

I'm trying to search and replace mobile numbers with the full international code.
So where rows have 07970000007 to replace the beginning with +447970000007
UPDATE tblMemberImportClub
SET msisdn = REPLACE(msisdn, '07', '+447')
WHERE INSTR(msisdn, '07') = 1;
But this also replaces the other matches:
+4479700000+447
I don't think i can use TRIM as some rows will already start with +447 and will therefore nor require any updates.
Thanks in advance for any assistance.
Use LIKE and INSERT():
UPDATE tblMemberImportClub
SET msisdn = INSERT(msisdn, 1, 2, '+447')
WHERE msisdn LIKE '07%';
INSERT() is a string function that replaces exactly the characters you specify (see here).
SELECT
CONCAT(
REPLACE(
LEFT('07970000007',2), '07', '+447'
),
SUBSTRING('07970000007', 3, CHAR_LENGTH('07970000007'))
)as replaced

How to replace only few characters from a string in mysql?

I have a field urn_sem.studentid that I'd like to replace a few characters in; for example:
ABC/2011/BCOMH_NC/I/12 → ABC/2011/BCOMH/I/12
ABC/2011/BCOMH_NC/I/24 → ABC/2011/BCOMH/I/24
I've tried this query:
SELECT REPLACE(studentid, 'KNC/2011/BCOMH_NC/', ' KNC/2011/BCOMH/')
FROM urn_sem
but it doesn't show the new value.
Do you want this:
update urn_sem
set studentid = REPLACE(studentid, 'KNC/2011/BCOMH_NC/', ' KNC/2011/BCOMH/')
where studentid like '%KNC/2011/BCOMH_NC/%'
The WHERE clause is optional. It ensures that the replace is only on rows that change.
And this sample query does not work?
SELECT REPLACE (studentid, '_', '') FROM urn_sem

SQL: search/replace but only the first time a value appears in record

I have html content in the post_content column.
I want to search and replace A with B but only the first time A appears in the record as it may appear more than once.
The below query would obviously replace all instances of A with B
UPDATE wp_posts SET post_content = REPLACE (post_content, 'A', 'B');
This should actually be what you want in MySQL:
UPDATE wp_post
SET post_content = CONCAT(REPLACE(LEFT(post_content, INSTR(post_content, 'A')), 'A', 'B'), SUBSTRING(post_content, INSTR(post_content, 'A') + 1));
It's slightly more complicated than my earlier answer - You need to find the first instance of the 'A' (using the INSTR function), then use LEFT in combination with REPLACE to replace just that instance, than use SUBSTRING and INSTR to find that same 'A' you're replacing and CONCAT it with the previous string.
See my test below:
SET #string = 'this is A string with A replace and An Answer';
SELECT #string as actual_string
, CONCAT(REPLACE(LEFT(#string, INSTR(#string, 'A')), 'A', 'B'), SUBSTRING(#string, INSTR(#string, 'A') + 1)) as new_string;
Produces:
actual_string new_string
--------------------------------------------- ---------------------------------------------
this is A string with A replace and An Answer this is B string with A replace and An Answer
Alternatively, you could use the functions LOCATE(), INSERT() and CHAR_LENGTH() like this:
INSERT(originalvalue, LOCATE('A', originalvalue), CHAR_LENGTH('A'), 'B')
Full query:
UPDATE wp_posts
SET post_content = INSERT(originalvalue, LOCATE('A', originalvalue), CHAR_LENGTH('A'), 'B');
With reference to https://dba.stackexchange.com/a/43919/200937 here is another solution:
UPDATE wp_posts
SET post_content = CONCAT( LEFT(post_content , INSTR(post_content , 'A') -1),
'B',
SUBSTRING(post_content, INSTR(post_content , 'A') +1))
WHERE INSTR(post_content , 'A') > 0;
If you have another string, e.g. testing then you need to change the +1 above to the according string length. We can use LENGTH() for this purpose. By the way, leave the -1 untouched.
Example: Replace "testing" with "whatever":
UPDATE wp_posts
SET post_content = CONCAT( LEFT(post_content , INSTR(post_content , 'testing') -1),
'whatever',
SUBSTRING(post_content, INSTR(post_content , 'testing') + LENGTH("testing"))
WHERE INSTR(post_content , 'testing') > 0;
By the way, helpful to see how many rows will be effected:
SELECT COUNT(*)
FROM post_content
WHERE INSTR(post_content, 'A') > 0;
If you are using an Oracle DB, you should be able to write something like :
UPDATE wp_posts SET post_content = regexp_replace(post_content,'A','B',1,1)
See here for more informations : http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions130.htm
Note : you really should take care of post_content regarding security issue since it seems to be an user input.
Greg Reda's solution did not work for me on strings longer than 1 character because of how the REPLACE() was written (only replacing the first character of the string to be replaced). Here is a solution that I believe is more complete and covers every use case of the problem when defined as How do I replace the first occurrence of "String A" with "String B" in "String C"?
CONCAT(LEFT(buycraft, INSTR(buycraft, 'blah') - 1), '', SUBSTRING(buycraft FROM INSTR(buycraft, 'blah') + CHAR_LENGTH('blah')))
This assumes that you are sure that the entry ALREADY CONTAINS THE STRING TO BE REPLACED! If you try replacing 'dog' with 'cat' in the string 'pupper', it will give you 'per', which is not what you want. Here is a query that handles that by first checking to see if the string to be replaced exists in the full string:
IF(INSTR(buycraft, 'blah') <> 0, CONCAT(LEFT(buycraft, INSTR(buycraft, 'blah') - 1), '', SUBSTRING(buycraft FROM INSTR(buycraft, 'blah') + CHAR_LENGTH('blah'))), buycraft)
The specific use case here is replacing the first instance of 'blah' inside column 'buycraft' with an empty string ''. I think a pretty intuitive and natural solution:
Find the index of the first occurrence of the string that is to be replaced.
Get everything to the left of that, not including the index itself (thus '-1').
Concatenate that with whatever you are replacing the original string with.
Calculate the ending index of the part of the string that is being replaced. This is easily done by finding the index of the first occurrence again, and adding the length of the replaced string. This will give you the index of the first char after the original string
Concatenate the substring starting at the ending index of the string
An example walkthrough of replacing "pupper" in "lil_puppers_yay" with 'dog':
Index of 'pupper' is 5.
Get left of 5-1 = 4. So indexes 1-4, which is 'lil_'
Concatenate 'dog' for 'lil_dog'
Calculate the ending index. Start index is 5, and 5 + length of 'pupper' = 11. Note that index 11 refers to 's'.
Concatenate the substring starting at the ending index, which is 's_yay', to get 'lil_dogs_yay'.
All done!
Note: SQL has 1-indexed strings (as an SQL beginner, I didn't know this before I figured this problem out). Also, SQL LEFT and SUBSTRING seem to work with invalid indexes the ideal way (adjusting it to either the beginning or end of the string), which is super convenient for a beginner SQLer like me :P
Another Note: I'm a total beginner at SQL and this is pretty much the hardest query I've ever written, so there may be some inefficiencies. It gets the job done accurately though.
I made the following little function and got it:
CREATE DEFINER=`virtueyes_adm1`#`%` FUNCTION `replace_first`(
`p_text` TEXT,
`p_old_text` TEXT,
`p_new_text` TEXT
)
RETURNS text CHARSET latin1
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'troca a primeira ocorrencia apenas no texto'
BEGIN
SET #str = p_text;
SET #STR2 = p_old_text;
SET #STR3 = p_new_text;
SET #retorno = '';
SELECT CONCAT(SUBSTRING(#STR, 1 , (INSTR(#STR, #STR2)-1 ))
,#str3
,SUBSTRING(#STR, (INSTR(#str, #str2)-1 )+LENGTH(#str2)+1 , LENGTH(#STR)))
INTO #retorno;
RETURN #retorno;
END
Years have passed since this question was asked, and MySQL 8 has introduced REGEX_REPLACE:
REGEXP_REPLACE(expr, pat, repl[, pos[, occurrence[, match_type]]])
Replaces occurrences in the string expr that match the regular
expression specified by the pattern pat with the replacement string
repl, and returns the resulting string. If expr, pat, or repl is NULL,
the return value is NULL.
REGEXP_REPLACE() takes these optional arguments:
pos: The position in expr at which to start the search. If omitted, the default is 1.
occurrence: Which occurrence of a match to replace. If omitted, the default is 0 (which means “replace all occurrences”).
match_type: A string that specifies how to perform matching. The meaning is as described for REGEXP_LIKE().
So, assuming you can use regular expressions in your case:
UPDATE wp_posts SET post_content = REGEXP_REPLACE (post_content, 'A', 'B', 1, 1);
Unfortunately for those of us on MariaDB, its REGEXP_REPLACE flavor is missing the occurrence parameter. Here's a regex-aware version of Andriy M's solution, conveniently stored as a reusable function as suggested by Luciano Seibel:
DELIMITER //
DROP FUNCTION IF EXISTS replace_first //
CREATE FUNCTION `replace_first`(
`i` TEXT,
`s` TEXT,
`r` TEXT
)
RETURNS text CHARSET utf8mb4
BEGIN
SELECT REGEXP_INSTR(i, s) INTO #pos;
IF #pos = 0 THEN RETURN i; END IF;
RETURN INSERT(i, #pos, CHAR_LENGTH(REGEXP_SUBSTR(i, s)), r);
END;
//
DELIMITER ;
It's simpler
UPDATE table_name SET column_name = CONCAT('A',SUBSTRING(column_name, INSTR(column_name, 'B') + LENGTH('A')));
For MYSQL version pre-5.6 and 8.0, I've used this pattern to fix my issue, it's a bit gross, but I hope it helps some of you guys:
SET #string = 'I love shop it is a terrific shop, I love eveything about it';
SET #shop_code = 'shop';
SET #shop_date = CONCAT(#shop_code, '__', DATE_FORMAT(NOW(), '%Y_%m_%d__%Hh%im%ss'));
SET #part1 = SUBSTRING_INDEX(#string, #shop_code, 1);
SET #shop_nb = ROUND( (LENGTH(#string) - LENGTH(REPLACE(#string, #shop_code,''))) / LENGTH(#shop_code) );
SET #part2 = SUBSTRING_INDEX(#string, #shop_code, -#shop_nb);
SET #string = CONCAT(#part1, #shop_date, #part2);
SELECT #string;
To keep the sample of gjreda a bit more simple use this:
UPDATE wp_post
SET post_content =
CONCAT(
REPLACE(LEFT(post_content, 1), 'A', 'B'),
SUBSTRING(post_content, 2)
)
WHERE post_content LIKE 'A%';

MySql: updating a column with the column's content plus something else

I'm don't have a lot of knowledge of MySql (or SQL in general) so sorry for the noobness.
I'm trying to update a bunch of String entries this way:
Lets say we have this:
commands.firm.pm.Stuff
Well I want to convert that into:
commands.firm.pm.print.Stuff
Meaning, Add the .print after pm, before "Stuff" (where Stuff can be any Alphanumerical String).
How would I do this with a MySql Query? I'm sure REGEXP has to be used, but I'm not sure how to go about it.
Thanks
Try something like this. It finds the last period and inserts your string there:
select insert(s, length(s) - instr(reverse(s), '.') + 1, 0, '.print')
from (
select 'commands.firm.pm.Stuff' as s
) a
To update:
update MyTable
set MyColumn = insert(MyColumn, length(MyColumn) - instr(reverse(MyColumn), '.') + 1, 0, '.print')
where MyColumn like 'commands.firm.pm.%'
Perhaps use a str_replace to replace commands.firm.pm to commands.firm.pm.print
$original_str = "commands.firm.pm.15hhkl15k0fak1";
str_replace("commands.firm.pm", "commands.firm.pm.print", $original_str);
should output: commands.firm.pm.print.15hhkl15k0fak1
then update your table with the new value...How to do it all in one query (get column value and do the update), I do not know. All I can think of is you getting the column value in one query, doing the replacement above, and then updating the column with the new value in a second query.
To update rows that end in '.Stuff' only:
UPDATE TableX
SET Column = CONCAT( LEFT( CHAR_LENGTH(Column) - CHAR_LENGTH('.Stuff') )
, '.print'
, '.Stuff'
)
WHERE Column LIKE '%.Stuff'
To update all rows - by appending .print just before the last dot .:
UPDATE TableX
SET Column = CONCAT( LEFT( CHAR_LENGTH(Column)
- CHAR_LENGTH(SUBSTRING_INDEX(Column, '.', -1))
)
, 'print.'
, SUBSTRING_INDEX(Column, '.', -1)
)
WHERE Column LIKE '%.%'