0

I have varchar field in the database that contains text. I need to replace every occurrence of a any 2 letter + 8 digits string to a link, such as VA12345678 will return /cs/page.asp?id=VA12345678

I have a regex that replaces the string but how can I replace it with a string where part of it is the string itself?

SELECT REGEXP_REPLACE ('test PI20099742', '[A-Z]{2}[0-9]{8}$', 'link to replace with')
FROM dual;

I can have more than one of these strings in one varchar field and ideally I would like to have them replaced in one statement instead of a loop.

3
  • Use backreferences. Google for that word (and Oracle) to see examples. docs.oracle.com/cd/B19306_01/server.102/b14200/functions130.htm Note though that some letters are not in the A-Z range; for example the letter m (lower case). Commented Mar 16, 2021 at 17:07
  • Thanks! I don't need lower case. Commented Mar 16, 2021 at 17:21
  • 1
    You don't need lower case today. This query will still be used two years from now, when the rules will change and you won't be there to help (you will be working in management already). "Defensive coding" anticipates such changes and accounts for them. Commented Mar 16, 2021 at 17:23

2 Answers 2

2

As mathguy had said, you can use backreferences for your use case. Try a query like this one.

SELECT REGEXP_REPLACE ('test PI20099742', '([A-Z]{2}[0-9]{8})', '/cs/page.asp?id=\1')
  FROM DUAL;
Sign up to request clarification or add additional context in comments.

2 Comments

Why do you have the $ at the end? The OP said specifically he may need to replace several such substrings in a single pass, which means they are not all at the end.
I had the $ at the end since OP had it in his original regex. You are correct in the fact that it's not needed if the replacement should be replaced anywhere within the string.
0

For such cases, you may want to keep the "text to add" somewhere at the top of the query, so that if you ever need to change it, you don't have to hunt for it.

You can do that with a with clause, as shown below. I also put some input data for testing in the with clause, but you should remove that and reference your actual table in your query.

I used the [:alpha:] character class, to match all letters - upper or lower case, accented or not, etc. [A-Z] will work until it doesn't.

with
  text_to_add (link) as (
      select '/cs/page.asp?id=' from dual
    )
, sample_strings (str) as (
      select 'test VA12398403 and PI83048203 to PT3904' from dual
    )
select regexp_replace(str, '([[:alpha:]]{2}\d{8})', link || '\1')
             as str_with_links
from   sample_strings cross join text_to_add
;

STR_WITH_LINKS                                                          
------------------------------------------------------------------------
test /cs/page.asp?id=VA12398403 and /cs/page.asp?id=PI83048203 to PT3904

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.