Oracle db: How to add spaces in specific positions in strings

萝らか妹 提交于 2020-05-23 10:22:43

问题


Suppose I have a string (varchar2) and I want to add a space wherever I have two consecutive a's. So for example: 'graanh' -> 'gra anh'.

OK, this is trivial to do, either with replace or regexp_replace. But both choke on three or more consecutive a's. For example:

SQL> select replace('aaaaa', 'aa', 'a a') from dual;

REPLACE
-------
a aa aa

SQL> select regexp_replace('aaaaa', 'aa', 'a a') from dual;

REGEXP_
-------
a aa aa

This is because the search for the "next" occurrence of the match pattern begins after the end of the "previous" one. Indeed, regexp_count('aaaaa', 'aa') returns 2, not 4.

The desired result is 'aaaaa' -> 'a a a a a'.

The problem, really, is that I don't want to replace the pattern 'aa'. What I do want to replace is the empty string BETWEEN a's on both sides of the empty string. So the description would be something like: Find all occurrences of an empty string with a's on both sides of it, and replace that empty string with a space.

Can this be done with string or regexp functions? Please do not offer solutions with recursive queries, or (the horror!) PL/SQL procedures; I know they can be done, but I am interested in whether there is a "natural" solution, a tool that exists precisely for this question, that I am missing.

Worst case, replace(replace('aaaaa', 'aa', 'a a'), 'aa', 'a a') will do the trick. Is this the best case as well?

Lest you think this is a weird requirement: I am experimenting with different methods of splitting comma-separated strings. Some of the methods have a very nasty habit of ignoring NULL tokens within such strings (that is, from two consecutive commas you don't get a NULL, as you should). So, before using those methods, one would have to parse the input string and add a space, or the string 'NULL', or something, between consecutive commas. Of course, it would be better to add a space after EVERY comma (and at the beginning of the string), and after splitting into tokens, to remove a space from the beginning of each token; but this raised the question I asked above, which I think has merit on its own.

Thank you!

EDIT (13 April 2020) I learned a lot about regular expressions since I first posted this question. Now I know the terminology for this. (I find that the explanation I gave is correct, I just wasn't using technical terms for it.) What we need here, to be able to add spaces everywhere they are needed in a single pass, is lookarounds - and Oracle regular expressions don't support them. END EDIT


回答1:


If you truly find PL/SQL the horror and recursive queries unnatural, then you probably have to go with replace(replace('aaaaa', 'aa', 'a a'), 'aa', 'a a'), as you already have proposed, albeit as "worst case". Why you consider this the worst case remains unclear to me.



来源:https://stackoverflow.com/questions/38537907/oracle-db-how-to-add-spaces-in-specific-positions-in-strings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!