1

I have a PostgreSQL database with a information table containing comments about people.

An example is Mr X, born the 18/12/1953 in Y...

I would like change the date's format to ISO 8601 (YYYY-MM-DD) with a unique PostgreSQL request or method.

I know how to detect the dates in my database: '(\d{2})/(\d{2})/(\d{4})'.

What is the best way to replace using this pattern?

I thought about a regex_replace mixed with a split but it's seems too complicated, I'm sure there is a simpler way.

If someone has a good tip, I take it!

Thanks

3
  • if you have some mask to match, regexp fit best I think Commented May 10, 2017 at 15:41
  • Is the date format persistent ? Is there any other non-date data having similar pattern ? Commented May 10, 2017 at 15:43
  • Have you tried anything to solve the task yet? Any patterns with regexp_replace? Commented May 10, 2017 at 15:44

1 Answer 1

1

Let's assume you have XX/XX/XXXX date-like substrings in your input that is always a date. Then, what you may use is a single REGEXP_REPLACE with a pattern containing capturing groups with corresponding backreferences in the replacement pattern, arranged in the required order and with desired separators:

REGEXP_REPLACE(s, '(\d{2})/(\d{2})/(\d{4})', '\3-\2-\1', 'g')

NOTE: you may enclose the whole pattern with \y, a word boundary, if you need to match those strings as whole words, '\y(\d{2})/(\d{2})/(\d{4})\y'. \d{2} matches two digits, \d{4} matches four digits. (...) creates a numbered capturing group (starting with ID 1 from left to right) and their contents are referenced with \n backreferences. 'g' replaces all occurrences in the string.

An online test:

CREATE TABLE table1
    (s character varying)
;

INSERT INTO table1
    (s)
VALUES
    ('Mr X, born the 18/12/1953 in Y...'),
    ('Mr Y, died the 18/12/2053 in Y...')
;
select REGEXP_REPLACE(s, '\y(\d+)/(\d+)/(\d+)\y', '\3-\2-\1', 'g') as Results from table1;

enter image description here

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks a lot ! I did not know the number capture group system, I just had the regex pattern.
What was the pattern? Please share. My answer could be more helpful then.
And I confirm that there are only dates in this format in my table. But just to know, changing the regex pattern to capture date formats would solve the case, right? Something like : REGEXP_REPLACE(s, '\y(<Day format>)/(<Month format>)/(<Year format>)\y', '\3-\2-\1', 'g')
I see I used a simplified regex in the demo. Actually, there is no construct for "day format" or "month format" in regex, it just matches (sequences of) chars of specific type/sets, that is all. You may make the date regex more precise, say, limiting the day value to 1-31 and month part to only match 1-12 with \y([012]?[0-9]|3[01])/(0?[1-9]|1[012])/(\d{4})\y. However, it will accept Feb 29, 30, 31, and Sept 31, etc. Still, it is "good-enough".
I had "(\d{2})/(\d{2})/(\d{4})". (Without the two '\y') I knew how to detect them, not how to replace. It's perfect, I just have to create my UPDATE request now.

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.