2016-07-23 4 views
2

문자열 (varchar2)이 있다고 가정하고 두 개의 연속 a를 가질 때마다 공백을 추가하고 싶습니다. 따라서 예 : 'graanh' -> 'gra anh'.오라클 db : 문자열의 특정 위치에 공백을 추가하는 방법

OK,이 작업은 replace 또는 regexp_replace과 같이 간단합니다. 그러나 둘 다 에 3 개의 이상의 연속적인 a의 질식이있다. 예 :

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 

"다음"일치 패턴 검색은 "이전"패턴의 끝 이후에 시작하기 때문입니다. 실제로 regexp_count('aaaaa', 'aa')은 4가 아니라 2를 반환합니다.

원하는 결과는 'aaaaa' -> 'a a a a a'입니다.

문제는 정말로 내가 패턴 'aa'을 바꾸고 싶지 않다는 것입니다. 내가 바꾸려는 것은 비어있는 문자열의 양쪽에 빈 문자열입니다. 따라서 설명은 다음과 같습니다. 빈 문자열의 모든 항목을 찾으면서 양쪽에 빈 문자열을 찾아 빈 문자열을 공백으로 대체하십시오.

문자열 또는 regexp 함수로이를 수행 할 수 있습니까? 은 재귀 쿼리 또는 PL/SQL 프로 시저 (공포!)가있는 솔루션을 제공하지 않습니다. 나는 그들이 할 수 있다는 것을 알고 있지만, "자연적"해결책이 있는지, 나는이 질문에 정확하게 존재하는 도구인지, 내가 빠졌는지에 관심이있다.

최악의 경우 replace(replace('aaaaa', 'aa', 'a a'), 'aa', 'a a')이 트릭을 수행합니다. 이 도 최상의 케이스입니까?

여러분은 이것이 이상한 요구 사항이라고 생각하지 않도록 쉼표로 구분 된 문자열을 여러 가지 방법으로 나누어 실험하고 있습니다. 일부 메소드는 그러한 문자열 내에서 NULL 토큰을 무시하는 매우 까다로운 습관을 가지고 있습니다 (즉, 두 개의 연속 쉼표에서 NULL을 얻지 못합니다). 따라서 이러한 메서드를 사용하기 전에 입력 문자열을 구문 분석하고 연속 된 쉼표 사이에 공백 또는 'NULL'등의 문자열을 추가해야합니다. 물론 각 쉼표 뒤에 (그리고 문자열의 시작 부분에) 공백을 추가하고 토큰으로 분할 한 다음 각 토큰의 시작 부분에서 공백을 제거하는 것이 좋습니다. 그러나 이것은 내가 위에서 물었던 질문을 제기했다. 나는 그것이 나 자신에게 공로가 있다고 생각한다.

감사합니다. 당신이 진정으로 자연스러운 PL/SQL 공포과 재귀 쿼리를 발견하면

+0

하! 이 게시물을 참고 자료로 사용하여 널 (null)을 허용하는 문자열을 구문 분석하는 방법에 대해 언급 할 때 편집자가 나타났습니다. :-) http://stackoverflow.com/a/31464699/2543416 –

+0

내장 된 건물은 어떻습니까? 물론 PL/SQL이 아닌 java를 사용하고 있습니까? –

+0

@ J.Chomel - 나는 그것을 할 수 있었다 (자바를 배운 후에); 질문은, 그것은'replace'에 대한 이중 호출보다 더 효율적일까요? 어떻게 든 문맥 전환은'replace'를 두 번 호출하는 것보다 더 비싸다고 생각합니다. 또한,이 질문에 대한 나의 주된 목적은 필자가 누락 한 문자열 기능이나 특징 또는 기술이 있는지를 배우는 것이 었습니다. 몇 달 후 더 배웠습니다. 좀 더 일반적인 질문에 대한 대답은 아니오라고 생각합니다. 감사! – mathguy

답변

1

는, 당신은 아마 당신이 이미 제안 "최악의 경우"으로이기는 것처럼, replace(replace('aaaaa', 'aa', 'a a'), 'aa', 'a a')로 이동합니다. 이 점을 고려하면 왜 최악의 경우은 나에게 불명확합니다.

+0

명확해야 함 : 재귀 쿼리를 항상 사용하며, PL/SQL이 일반 SQL보다 훨씬 잘 작동하는 것으로 알고있는 하나 이상의 사례가 있습니다 (Eratosthenes 알고리즘 구현).나는 재귀 CTE가 부자연스럽고 PL/SQL 불필요 (앞서 언급 한 "최악의 경우"보다 간단하고 나은 솔루션을 허용 할 방법이 없기 때문에)이 문제에 대한 의미였습니다. 방금 FOR 루프를 사용하여 솔루션을보고 싶지 않았습니다. 재귀 적 CTE 또는 PL/SQL 솔루션을 replace (replace())보다 간단하게 제안 할 수 있다면 꼭 제안하십시오. – mathguy

+0

제안 된 솔루션이 (최악의 경우보다) 악화되지 않아야한다는 점에서 "최악의 경우"라고 생각합니다. "가장 좋은 경우"는 패턴을 검색하고 패턴에서 하위 패턴을 바꿀 수있는 정규 표현식 (또는 유사한) 솔루션입니다. 미안하지만 분명하지 않다면 최선을 다했지만 설명에 실패했습니다. – mathguy

관련 문제