Reputation: 2032
how I can write this regular expression?
origin => 'fo3o321bar423ba 234 z' result => "fo 3 o 321 bar 423 ba 234 z"
select regexp_replace(trim(regexp_replace(trim(regexp_replace('fo3o321bar423ba 234 z', E'([a-z]*[0-9]*)', E'\\1 ', 'g')), E'([0-9]*[a-z]*)', E'\\1 ', 'g')),'[\s.]+', ' ', 'g')
Upvotes: 2
Views: 310
Reputation: 626927
You can achieve what you want with the following regexp_replace
:
SELECT regexp_replace('fo3o321bar423ba 234 z', '([^0-9]|^)([0-9]+)(?=[^0-9]|$)', '\1 \2 ', 'g');
See demo
Result: fo 3 o 321 bar 423 ba 234 z
Regex matches:
(^|[^0-9])
- start of string or a non-digit and stores in Group 1([0-9]+)
- 1 or more digits(?=[^0-9]|$)
- a lookahead check if there is a non-digit or end of string right after.The replacement string - '\1 \2 '
- back references the captured groups 1 and 2 defined in the pattern with (...)
.
'g'
means we want to replace all occurrences, not just the first.
Upvotes: 1
Reputation: 48256
You'll probably need a function to do it. PL/Perl might be best as Perl supports regex look-behind, but here is some working JavaScript, as that's all I have:
create extension if not exists plv8;
create or replace function delim(s text) returns text language plv8 as $$
var match;
var result = [];
while (Boolean(match = s.match(/([A-Z]+|[A-Z]?[a-z]+|[0-9]+|([^a-zA-Z0-9])+)$/))) {
if (!match[2]) {
result.unshift(match[1]); /* don't return non alphanumeric tokens */
}
s = s.substring(0, s.length - match[1].length);
}
return result.join(" ");
$$;
select delim('fo3o321bar423ba 234 z'); --result fo 3 o 321 bar 423 ba 234 z
Upvotes: 0