I'm getting the error invalid regular expression: parentheses () not balanced while executing a query. The error refers to this part:
substring(every_x1, '\m[0-9]*\.?[0-9]'),
substring(every_x2, '\m[0-9]*\(?|-|to|TO)'),
substring(every_x2, '\m[0-9]*\(?|time|TIME)')
I checked it in an online parentheses checker, and it's supposed to be okay. What am I doing wrong?
I dont know what is the exact pattern you are looking but if you were looking to find the actual "(" (parentheses) sign maybe you should escape it the second time also, somethin like in this example:
select substring(every_x2, '\m[0-9]*\(?|-|to|TO\)')::float as part_1
Try this regular expression '\m(\d+(?:\s*-\s*|\s*to\s*)\d+)\M').
select substring('123 12-56 xyz' from '\m(\d+(?:\s*-\s*|\s*to\s*)\d+)\M');
-- 12-56
select substring('123 12 to 56 xyz' from '\m(\d+(?:\s*-\s*|\s*to\s*)\d+)\M');
-- 12 to 56
Related
In PostgreSQL, I have the following text type in a column value.
{186=>15.55255158, 21=>5123.43494408, 164=>0.0}
I would like to select the numbers before the => character and use the ouput in a subquery. So the output should be:
186
21
164
I tried several regex statement but it does not work. Any help would be appreciated.
You need to both use a regular expression, and a function to extract the values matched from the regular expression into a data set. The ~ operator is only used to match in a where clause. You need the REGEXP_MATCHES function.
SELECT REGEXP_MATCHES(your_column_name, '(\d+)=>', 'g')
FROM your_table_name
The 'g' option will return multiple matches, rather than just the first.
SQL Fiddle
you can use the simple substring(column_name from '(\d+)=>') to extract the appropriate data.
please, I have in Oracle table this texts (as 2 records)
"Sample text with replace parameter %1%"
"You reached 90% of your limit"
I need replace %1% with specific text from input parameter in Oracle Function. In fact, I can have more than just one replace parameters. I have also record with "Replace this %12% with real value"
This functionality I have programmed:
IF poc > 0 THEN
FOR i in 1 .. poc LOOP
p := get_param(mString => mbody);
mbody := replace(mbody,
'%' || p || '%', parameters(to_number(p, '99')));
END LOOP;
END IF;
But in this case I have problem with text number 2. This functionality trying replace "90%" also and I then I get this error:
ORA-06502: PL/SQL: numeric or value error: NULL index table key value
It's a possible to avoid try replace "90%"? Many thanks for advice.
Best regards
PS: Oracle version: 10g (OCI Version: 10.2)
Regular expressions can work here. Try the following and build them into your script.
SELECT REGEXP_REPLACE( 'Sample text with replace parameter %1%',
'\%[0-9]+\%',
'db_size' )
FROM DUAL
and
SELECT REGEXP_REPLACE( 'Sample text with replace parameter 1%',
'\%[0-9]+\%',
'db_size' )
FROM DUAL
The pattern is pretty simple; look for patterns where a '%' is followed by 1 or more numbers followed by a '%'.
The only issue here will be if you have more than one replacement to make in each string and each replacement is different. In that case you will need to loop round the string each time replacing the next parameter. To do this add the position and occurrence parameters to REGEXP_REPLACE after the replacement string, e.g.
REGEXP_REPLACE( 'Sample text with replace parameter %88888888888%','\%[0-9]+\%','db_size',0,1 )
You are getting the error because at parameters(to_number(p, '99')). Can you please check the value of p?
Also, if the p=90 then then REPLACE will not try to replace "90%". It will replace "%90%". How have you been sure that it's trying to replace "90%"?
I am running on a postgresql 8.2.15 database.
I am trying to run a query that does a join using regular expressions. My current query is:
SELECT *
FROM USCITY a join USCITY2 b
ON b.usps in regexp_matches(a.city, '.* (?= [^\\s]*, [^\\s]*$)');
this produces the error:
"ERROR: syntax error at or near "regexp_matches"
Position: 101"
I have checked to see that the regexp_matches function works using
SELECT regexp_matches(city, '.* (?= [^\\s]*, [^\\s]*$)')
FROM CITY2;
Thanks for your help.
If I run this query:
SELECT 'Via Orologio 122 A' SIMILAR TO '(Strada|Via) % [0-9]+( [A-Z])?';
I expect to get TRUE. Version 9.1.8 of postgreSQL returns the expected value, but in version 8.3 it returns FALSE. I think that the problem is the final question mark. In fact, the query:
SELECT 'Via Orologio 122 A' SIMILAR TO '(Strada|Via) % [0-9]+( [A-Z])';
Returns TRUE in both versions.
Anyone knows which is the difference between the two versions?
From changelog of 8.3.2:
Fix a corner case in regular-expression substring matching
(substring(string from pattern)) (Tom)
The problem occurs when there
is a match to the pattern overall but the user has specified a
parenthesized subexpression and that subexpression hasn't got a match.
An example is substring('foo' from 'foo(bar)?'). This should return
NULL, since (bar) isn't matched, but it was mistakenly returning the
whole-pattern match instead (ie, foo)
When switching to a regular expression (~), the drop-in replacement would be:
SELECT 'Via Orologio 122 A' ~ '^(?:(?:Strada|Via) .* [0-9]+(?: [A-Z])?)$'
left-anchored and right-anchored
with *, not +
non-capturing parentheses
Hint:
You can let Postgres translate SIMILAR TO expressions for you with the technique outlined in tis related answer on dba.SE.
Following Craig Ringer's advice, changing to:
SELECT 'Via Orologio 122 A' ~ '(Strada|Via) .+ [0-9]+( [A-Z])?';
solved the problem. '~' seems to be a definitely better solution than 'SIMILAR TO'
I am trying to write a common regular expression for the below 3 cases:
Supernatural_S07E23_720p_HDTV_X264-DIMENSION.mkv
the.listener.313.480p.hdtv.x264-2hd.mkv
How.I.met.your.mother.s02e07.hdtv.x264-xor.avi
Now my regular exoression should remove the series name from the original string i,e the output of above string will be:
S07E23_720p_HDTV_X264-DIMENSION.mkv
313.480p.hdtv.x264-2hd.mkv
s02e07.hdtv.x264-xor.avi
Now for the basic case of supernatural string I wrote the below regex and it worked fine but as soon as the series name got multiple words it fails.
$string =~ s/^(.*?)[\.\_\- ]//i; #delimiter can be (. - _ )
So, I have no idea how to proceed for the aboves cases I was thinking along the lines of \w+{1,6} but it also failed to do the required.
PS: Explanation of what the regular expression is doing will be appreciated.
you can detect if the .'s next token contains digit, if not, consider it as part of the name.
HOWEVER, I personally think there is no perfect solution for this. it'd still meet problem for something like:
24.313.480p.hdtv.x264-2hd.mkv // 24
Warehouse.13.s02e07.hdtv.x264-xor.avi // warehouse 13
As StanleyZ said, you'll always get into trouble with names containing numbers.
But, if you take these special cases appart, you can try :
#perl
$\=$/;
map {
if (/^([\w\.]+)[\.\_]([SE\d]+[\.\_].*)$/i) {
print "Match : Name='$1' Suffix='$2'";
} else {
print "Did not match $_";
}
}
qw!
Supernatural_S07E23_720p_HDTV_X264-DIMENSION.mkv
the.listener.313.480p.hdtv.x264-2hd.mkv
How.I.met.your.mother.s02e07.hdtv.x264-xor.avi
!;
which outputs :
Match : Name='Supernatural' Suffix='S07E23_720p_HDTV_X264-DIMENSION.mkv'
Match : Name='the.listener' Suffix='313.480p.hdtv.x264-2hd.mkv'
Match : Name='How.I.met.your.mother' Suffix='s02e07.hdtv.x264-xor.avi'
note : aren't you doing something illegal ? ;)