Regex not working in APEX, working on RegexPlanet - regex

I am trying to create a validation for a field where the user should enter an Oracle JDBC Thin connection URL, like:
jdbc:oracle:thin:#//192.168.2.1:1521/XE
jdbc:oracle:thin:192.168.2.1:1521:X01A
jdbc:oracle:thin:#//192.168.2.1:1521/COM.EXAMPLE
I tried testing the regex with RegexPlanet and it says it's working (the regex I am using):
^jdbc:oracle:thin:[#//]*[.\w]+:\d+[:]*[/]*[a-zA-Z0-9.]*$
But when I try to validate the form using this regex it shows the error message, even when I am using the exact same URL's as the one's above. Other validations are working just fine.

A JDBC Thin Driver Connection string can take one of these formats:
jdbc:oracle:thin:#[HOST][:PORT]:SID
jdbc:oracle:thin:#//[HOST][:PORT]/SERVICE
jdbc:oracle:thin:[USER/PASSWORD]#[HOST][:PORT]:SID
jdbc:oracle:thin:[USER/PASSWORD]#//[HOST][:PORT]/SERVICE
Where HOST can be an IP Address or a name.
If you ignore the username/password then a regular expression to match is something like:
^jdbc:oracle:thin:#(//)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\w+):\d+[:/][a-zA-Z0-9.]+$
(although it's not perfect - but a perfect regular expression to match this would be huge)
Query:
WITH connections ( conn ) AS (
SELECT 'jdbc:oracle:thin:#//192.168.2.1:1521/XE' FROM DUAL UNION ALL
SELECT 'jdbc:oracle:thin:#192.168.2.1:1521:X01A' FROM DUAL UNION ALL
SELECT 'jdbc:oracle:thin:#//192.168.2.1:1521/COM.EXAMPLE' FROM DUAL
)
SELECT *
FROM connections
WHERE REGEXP_LIKE( conn, '^jdbc:oracle:thin:#(//)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\w+):\d+[:/][a-zA-Z0-9.]+$' );
Results:
CONN
------------------------------------------------
jdbc:oracle:thin:#//192.168.2.1:1521/XE
jdbc:oracle:thin:#192.168.2.1:1521:X01A
jdbc:oracle:thin:#//192.168.2.1:1521/COM.EXAMPLE

Related

BigQuery Regex to get extract user between string and a character

{"sha":"65a0dbec42b65b6acc30dc1f814515c7c2174387","author":{"name":"Kubernetes Prow Robot","email":"5c2029016e1607554af814ace319699a11cecd88#users.noreply.github.com"},"message":"Merge pull request #97297 from saad-ali/automated-cherry-pick-of-#97259-upstream-release
I'm trying to extract the user in the github commit message.
In this example, it would return saad-ali
The user is always after the phrase Merge pull request #97297 from and the next /. The pull request # would be different from line to line though and the expression would need to work for any number.
Thanks
Using Regular expression is possible:
SELECT *,
regexp_extract(A,r"request #\d* from ([^/]*)/") as B
from (
select """{"sha":"65a0dbec42b65b6acc30dc1f814515c7c2174387","author":{"name":"Kubernetes Prow Robot","email":"5c2029016e1607554af814ace319699a11cecd88#users.noreply.github.com"},"message":"Merge pull request #97297 from saad-ali/automated-cherry-pick-of-#97259-upstream-release
""" as A
)
For more complex question, JSON parsing would be a better option.

String matching in URL using Hive / Spark SQL

I have two tables, one containing list of URL and other having a list of words. My requirement is to filter out the URLs containing the words.
For eg:
URL
https://www.techhive.com/article/3409153/65-inch-oled-4k-tv-from-lg-at-a-1300-dollar-discount.html
https://www.techradar.com/in/news/lg-c9-oled-65-inch-4ktv-price-drop
https://www.t3.com/news/cheap-oled-tv-deals-currys-august
https://indianexpress.com/article/technology/gadgets/lg-bets-big-on-oled-tvs-in-india-to-roll-out-rollable-tv-by-year-end-5823635/
https://www.sony.co.in/electronics/televisions/a1-series
https://www.amazon.in/Sony-138-8-inches-Bravia-KD-55A8F/dp/B07BWKVBYW
https://www.91mobiles.com/list-of-tvs/sony-oled-tv
Words
Sony
Samsung
Deal
Bravia
Now I want to filter any URL that has any of the words. Normally i would do a
Select url from url_table where url not like '%Sony%' or url not like '%Samsung%' or url not like '%Deal%' or not like '%Bravia%';
But that's a cumbersome and not scalable way to do it. What is the best way to achieve this? How do I use a not like function to the words table?
Using regex:
where url not rlike '(?i)Sony|Samsung|Deal|Bravia'
(?i) means case insesitive.
And now let's build the same regexp from the table with words.
You can aggregate list of words from the table and pass it to the rlike. See this example:
with
initial_data as (--replace with your table
select stack(7,
'https://www.techhive.com/article/3409153/65-inch-oled-4k-tv-from-lg-at-a-1300-dollar-discount.html',
'https://www.techradar.com/in/news/lg-c9-oled-65-inch-4ktv-price-drop',
'https://www.t3.com/news/cheap-oled-tv-deals-currys-august',
'https://indianexpress.com/article/technology/gadgets/lg-bets-big-on-oled-tvs-in-india-to-roll-out-rollable-tv-by-year-end-5823635/',
'https://www.sony.co.in/electronics/televisions/a1-series',
'https://www.amazon.in/Sony-138-8-inches-Bravia-KD-55A8F/dp/B07BWKVBYW',
'https://www.91mobiles.com/list-of-tvs/sony-oled-tv'
) as url ) ,
words as (-- replace with your words table
select stack (4, 'Sony','Samsung','Deal','Bravia') as word
),
sub as (--aggregate list of words for rlike
select concat('''','(?i)',concat_ws('|',collect_set(word)),'''') words_regex from words
)
select s.url
from initial_data s cross join sub --cross join with words_regex
where url not rlike sub.words_regex --rlike works fine
Result:
OK
url
https://www.techhive.com/article/3409153/65-inch-oled-4k-tv-from-lg-at-a-1300-dollar-discount.html
https://www.techradar.com/in/news/lg-c9-oled-65-inch-4ktv-price-drop
https://indianexpress.com/article/technology/gadgets/lg-bets-big-on-oled-tvs-in-india-to-roll-out-rollable-tv-by-year-end-5823635/
Time taken: 10.145 seconds, Fetched: 3 row(s)
Also you can calculate sub subquery separately and pass it's result as a variable instead of cross join in my example. Hope you got the idea.

Making unique slug url in Oracle

I am trying to make unique slug URL in oracle using with regular expression. How can I get numeric value end of URL like that lorem-ipsum-dolor-2. My purpose that; Before I check inserted title if exist on table, check it numeric value end of URL if exist slug URL, if has numeric value increase it and save. I have tried the following regular expression that worked properly in C# but it not work in Oracle.
select regexp_like('lorem-ipsum-dolor-2','(\d+)*$') from dual;
What you are doing is almost correct.
But instead of regexp_like' you need to useregexp_substr`:sp
select regexp_substr('lorem-ipsum-dolor-2','\d+$') from dual;
If you are using oracle APEX, and I can assume that's the case if you are working with URLs, than you can use
select apex_string_util.to_slug('Any, Text!;') from dual;
>> any-text

How to exclude a specific string/pattern from a regular expression in oracle?

I need an urgent help about an exclusion case in a regular expression (oracle).
The main regexp is that:
1([^4][:;]|[0-9][^:;].*)
I need to modify or enhance this regexp in order to exclude a spesific string "1013;" but could not achieve it. I have been searching a solution way for two days but could not find anything that works in oracle.
The most popular solution alternative (?!stringToExclude)Regexp is not working in oracle. (the version I have: Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production)
Do you have any idea about this issue? How can i overcome this problem?
my test sql statement checking the validation of new regexp is that:
select regexp_substr('1013;', '1([^34][:;]|[0-9][^:;].*)') from dual --> returns 1013;
select regexp_substr('10133;', '1([^34][:;]|[0-9][^:;].*)') from dual --> returns 10133;
select regexp_substr('1013;', 'to be regexp') from dual --> should return nothing
select regexp_substr('1013', 'to be regexp') from dual --> should return nothing
select regexp_substr('1013:', 'to be regexp') from dual --> should return nothing
select regexp_substr('10133;', 'to be regexp') from dual --> should return 10133;
try to replace the string you want to exclude with a string that would not be found by your regexp. e.g
with str as
(
select '1013;' as s from dual
union
select '1013' from dual
union
select '1013:' from dual
union
select '10133;' from dual
)
select
s
, regexp_substr(s, '1([^34][:;]|[0-9][^:;].*)') --> regexp
, regexp_replace(s,'^1013($|:|;)','x') --> replaced string
, regexp_substr(regexp_replace(s,'^1013($|:|;)','x')
, '1([^34][:;]|[0-9][^:;].*)') --> regexp with replaced string
from
str
;

RegEx in the select for DB2

I have a table with one column having a large json object in the format below. The column datatype is VARCHAR
column1
--------
{"key":"value",....}
I'm interested in the first value of the column data
in regex I can do it by .*?:(.*),.* with group(1) giving me the value
How can i use it in the select query
Don't do that, it's bad database design. Shred the keys and values to their own table as columns, or use the XML data type. XML would work fine because you can index the structure well, and you can use XPATH queries on the data. XPATH supports regexp natively.
You can use regular expression with xQuery, you just need to call the function matches from a SQL query or a FLORW query.
This is an example of how to use regular expressions from SQL:
db2 "with val as (
select t.text
from texts t
where xmlcast(xmlquery('fn:matches(\$TEXT,''^[A-Za-z 0-9]*$'')') as integer) = 0
)
select * from val"
For more information:
http://pic.dhe.ibm.com/infocenter/db2luw/v10r5/topic/com.ibm.db2.luw.xml.doc/doc/xqrfnmat.html
http://angocadb2.blogspot.fr/2014/04/regular-expressions-in-db2.html
DB2 doesn't have any built in regex functionality, unfortunately. I did find an article about how to add this with libraries:
http://www.ibm.com/developerworks/data/library/techarticle/0301stolze/0301stolze.html
Without regexes, this operation would be a mess. You could make a function that goes through the string character by character to find the first value. Or, if you will need to do more than this one operation, you could make a procedure that parses the json and throws it into a table of keys/values. Neither one sounds fun, though.
In DB2 for z/OS you will have to pass the variable to XMLQUERY with the PASSING option
db2 "with val as (
select t.text
from texts t
where xmlcast(xmlquery('fn:matches($TEXT,''^[A-Za-z 0-9]*$'')'
PASSING t.text as "TEXT") as integer) = 0
)
select * from val"