I have a table with a column of string. within the string there are single quote which I want to get rid of all single quotes.for example:
"''hey, hey, we're the monkees''"
my regex works perfect and select all the values containing single quotes.
select regexp_replace(colName, '%''%', '') from tblName;
but it does not update my table when I want to replace this regex with nothing.
UPDATE tblName SET colName = regexp_replace(colName, '%''%', '');
I also checked this one
UPDATE tblName SET colName = replace(colName, '%''%', '');
Different functions and operators in Postgres use one of three different pattern matching languages, as described in a dedicated section of the manual.
The % form you are using here is the SQL LIKE syntax, where % represents "any number of any character". But the function you are using, regexp_replace, expects a Posix regular expression, where the equivalent would be .* (. meaning any character, * meaning repeat zero or more times).
Also note that LIKE expressions have to match the whole string, but a Posix regex doesn't, unless you explicitly match the start of the string with ^ and the end with $.
So the direct translation of '%''%' would be '^.*''.*$', giving you this:
UPDATE tblName SET colName = regexp_replace(colName, '^.*''.*$', '');
In practice, this would give the same effect as the simpler:
UPDATE tblName SET colname='' WHERE colname LIKE '%''%';
Your actual use case is much simpler: you want to replace all occurrences of a fixed string (', which will need to be quoted and escaped as '''') with another fixed string (the empty string, written ''). So you don't need any pattern matching at all, just straight replacement using replace:
UPDATE tblName SET colname=replace(colname, '''', '');
This will probably be faster if you limit it to rows that contain an apostrophe to begin with:
UPDATE tblName SET colname=replace(colname, '''', '') WHERE colname LIKE '%''%';
% is not an regexp character
try this
select regexp_replace(colName, $$'$$, '','g') from tblName;
($$ is use to surround your string instead of ' to simplify the query)
(,'g') is use to continue after the first quote is found.
UPDATE tblName SET colName = regexp_replace(colName, $$'$$, '','g');
Related
Base String:
SELECT (sum([column.one]) / sum([column.two])) AS [sum / sum], [column.three] AS [column.three] FROM [database.table] GROUP BY [column.three] ORDER BY [column.three] ASC
Resultant String:
SELECT (sum([column.one]) / sum([column.two])) AS [sum___sum], [column.three] AS [column.three] FROM [database.table] GROUP BY [column.three] ORDER BY [column.three] ASC
Here [sum / sum] could change to some other format like [sum * distinct] or [max + min - distinct]
What I have till now:
Replace all the values with [] around them with _:
(s/replace sql #"\[(.*?)\]" "_")
What I am trying:
If I can get the value that got matched, I can replace all special characters except dot (.) with an underscore.
(s/replace sql #"\[(.*?)\]" #(s/replace "$1" #"[\/\*\-\+\(\)\\\s]" "_"))
More clarity:
In short, anything inside [] can only be a combination of alphanumeric, dots, and underscores. Otherwise replace that character with underscore (_).
[Repeating my answer from comments]
In this case "$1" is not a valid syntax.
You are trying to replace something in literal string "$1", not in the matched string. You should operate the match passed by first replace in the second one. Just replace "$1" with (second %)
Ugly way would be simple line splitting with subs to first part and second part. Then add you "sum___sum" between those parts.
That would be quite simple if part to be replaced is always first "AS [" in your sql query string. You can use that to find right index-of from your string. That way you wouldn't need the regexp.
As mentioned earlier inserting string straight to the query might offer possibility to attack into your database using sql injection.
Better way would be use parameter(s) in your original query or create the query as a prepared statement.
Hope here is the right place to write ask this question.
I am preparing a script to import to a database using notepad++.
I have a huge file that has rows like that:
(10496, '69055-230', 'Rua', '5', 'Manaus', 'Parque 10 de Novembro',
'AM'),
INSERT INTO dne id, cep, tp_logradouro, logradouro, cidade,
bairro, uf VALUES
Is there a way using FIND/REPLACE to replace the ',' to ';' on every line before the INSERT statement?
I am not sure how to match the end of the line before a specific word.
The result would be
(10496, '69055-230', 'Rua', '5', 'Manaus', 'Parque 10 de Novembro',
'AM');
INSERT INTO dne id, cep, tp_logradouro, logradouro, cidade,
bairro, uf VALUES
Find what: ,(?=\s*INSERT)
Replace with: ;
Description
, matches a literal comma
(?=\s*INSERT) is a lookeahead that will assert for (but won't consume)
\s* any number of white spaces (including newlines)
INSERT as literal
If you also want to replace any commas before the end of the file, use
,(?=\h*\R\h*INSERT|\s*\z)
Note both expressions would fail if you have another instance of a comma followed by INSERT that shouldn't be replaced, but in that case you should specify it in the question.
You don't even need a regular expression for that.
Select Extended in Search Mode
Replace ,\nINSERT INTO with ;\nINSERT INTO
This matches , at the end of a line just before INSERT INTO at the beginning of the next line. Keep in mind that \n will match only in a Linux/Unix/Mac OS X file. For Windows use \r\n, for Mac OS Classic \r (reference).
Using sublim text or notepad++, click CTRL+h and replace all ")INSERT," by ");INSERT"
I expect that the INSERT statements will all have the form:
INSERT INTO table col1, col2, col3, ...
VALUES (val1, val2, val3, ...),
^^ what you want to replace
Assuming that the only place that ), will be observed is the end of the VALUES line, then you can just can just do the following replacement:
Find: ),$
Replace: );$
You can do this replacement with the regex option enabled.
I have a PL/SQL procedure and I need to take a string and remove all characters that aren't alphabetic. I've seen some examples and read documentation about the REGEXP_REPLACE function but can't understand how it functions.
This is not a duplicate because I need to remove punctuation, not numbers.
Either:
select regexp_replace('1A23B$%C_z1123d', '[^A-Za-z]') from dual;
or:
select regexp_replace('1A23B$%C_z1123d', '[^[:alpha:]]') from dual;
The second one takes into account possible other letters like:
select regexp_replace('123żźć', '[^[:alpha:]]') from dual;
Result:
żźć
Also to answer your question about how the functions works: the first parameter is the source string, the second - a regular expression - everything which will be matched to it, will be replaced by the third argument (optional, NULL by default, meaning all matched characters will just be removed).
Read more about regular expressions:
http://docs.oracle.com/cd/B19306_01/appdev.102/b14251/adfns_regexp.htm
you can use regexp like that:
SELECT REGEXP_REPLACE(UPPER('xYztu-123-hello'), '[^A-Z]+', '') FROM DUAL;
also answered here for non-numeric chars
Try this:
SELECT REGEXP_REPLACE('AB$%c','[^a-zA-Z]', '') FROM DUAL;
Or
SELECT REGEXP_REPLACE( your_column, '[^a-zA-Z]', '' ) FROM your_table;
Read here for more information
I have input string something like :
1.2.3.4_abc_4.2.1.44_1.3.4.23
100.11.11.22_xyz-abd_10.2.1.2_12.2.3.4
100.11.11.22_xyz_123_10.2.1.2_1.2.3.4
I have to replace the first string formed between two ipaddress which are separated by _, however in some string the _ is part of the replacement string (xyz_123)
I have to find the abc, xyz-abd and xyz_123 from the above string, so that I can replace with another column in that table.
_.*?_(?=\d+\.)
matches _abc_, _xyz-abd_ and _xyz_123_ in your examples. Is this working for you?
DECLARE
result VARCHAR2(255);
BEGIN
result := REGEXP_REPLACE(subject, $$_.*?_(?=\d+\.)$$, $$_foo_$$);
END;
Probably this is enough:
_[^.]+_
and replace with
_Replacement_
See it here on Regexr.
[^.]+ uses a negated character class to match a sequence of at least one (the + quantifier) non "." characters.
I am also matching a leading and a trailing "_", so you have to put it in again in the replacement string.
If PostgreSQL supports lookbehind and lookahead assertions, then it is possible to avoid the "_" in the replacement string:
(?<=_)[^.]+(?=_)
See it on Regexr
In order to map match first two "" , as #stema and #Tim Pietzcker mentioned the regex works. Then in order to append "" to the column , which is what I was struggling with, can be done with || operator as eg below
update table1 set column1=regexp_replace(column1,'.*?(?=\d+.)','' || column2 || '_')
Then for using the another table for update query , the below eg can be helpfull
update table1 as t set column1=regexp_replace(column1,'.*?(?=\d+.)','' || column2 || '_') from table2 as t2 where t.id=t2.id [other criteria]
I am struggling with the regex replacement solution that would remove all the text that are between quotes from VARCHAR2 field even if the text between these quotes has quoted text as well
For example text:
'text start 'text inside' text end' leftover 'some other text'
after regex replacement should contain: leftover
What I have came up with is this code:
with tbl as (
select
'''text start ''text inside'' text end'' leftover ''some other text''' as str
,'\''(.*?)\''' as regex
from dual
)
select
tbl.str as strA
,regexp_replace(tbl.str,tbl.regex, '') as strB
from tbl;
but the text between subquotes still remains.
Is it even possible to achieve this with regular expressions, or should I split and analyze the contents in some loop ?
An ideal solution would be if it could handle infinite levels occurrences of quoted text inside quoted text.
An ideal solution would be if it could handle infinite levels occurrences of quoted text inside quoted text.
It's impossible with a single regular expression.
Neither recursive regexps, nor recursive capture buffers are available in Oracle.
UPD :
But it could be done by SQL:
with tbl as (
select
'''text start ''text inside'' text end'' leftover ''some other text'''
as str
from dual
)
select
listagg(text) within group (order by n)
from
(
select
n,
sum(decode(regexp_replace(str, '^(.*?([<>])){'||n||'}.*$', '\2'),
'<', 1, '>', -1, 0)) over (order by n) as nest,
regexp_replace(str, '^(.*?[<>]){'||n||'}([^<>]*).*$', '\2') as text
from
( select regexp_replace(regexp_replace(str, '(\s|^)''', '\1<'),
'''(\s|$)', '>\1') as str from tbl ),
( select level-1 as n from dual
connect by level-1 <= (select regexp_count(str, '''') from tbl) )
)
where nest = 0
fiddle
try
, '^[^'']*(''.*'')[^'']*$' as regex
caveat: this will dumbly capture all content between the first and the last occurrence of single quotes inside tested text in capture group 1, including the outermost quotes themselves. in particular it does not check for proper nesting.
more important your replacement expr will be more complex:
, CASE WHEN REGEXP_INSTR(test, regex) > 0
THEN REPLACE ( test, REGEXP_REPLACE(test, regex, '\1'), '' )
ELSE test
END
if the regexp matches, the capture group is extracted first to be used in an ordinary replacement (this works because the matched portion is guaranteed to be maximal).
IMPORTANT: the solution won't produce the desired result in the particular context you have supplied. however, you cannot fare any better with plsql regexp functions since the oracle regex engine does not offer extensions to express recursion in the pattern (as eg. pcre do). you need this facility to resolve nesting constructs (ie. perform balanced counting).