2010-11-26 2 views
1

, например, у меня есть строка 'This Is An Example Of The String'
и я хочу, чтобы вернуть этот результат 'This is an Example of the String'
==> Я хочу, чтобы все 'Is', '' 'Of' и '' в нижних регистрах, остальное должно оставаться в Initcap.SQL - Обработка строк

Как это можно сделать в простом и уникальном запросе? вот мой запрос в нижний регистр только «Of»:

SELECT 'This Is An Example Of The String', 
     CASE 
     WHEN 'This Is An Example Of The String' like '% Of %' 
     THEN replace('This Is An Example Of The String', ' Of ', ' of ') 
     END 
    FROM dual ; 

Спасибо!

+0

Возможно, это можно сделать с помощью regexp_replace(), но я никогда не использовал его с группами регулярных выражений (которые в этом случае нужны) – 2010-11-26 14:36:09

ответ

4

Попробуйте это:

SELECT REPLACE(REPLACE(REPLACE(REPLACE('This Is An Example Of The String', 'Of', 'of'), 'The', 'the'), 'An', 'an'), 'Is', 'is') FROM dual; 

Я чувствую себя немного грязный после записи, что, хотя.

Редактировать: Убрано дополнительное «an» заменить, затем добавить отступ, а затем удалить отступ еще раз. Это выглядит уродливо, как бы вы его не обернули.

+1

Я чувствую себя немного грязным, читая его, но вы правы! :) – Timbo 2010-11-26 14:33:04

+0

Иногда нужно мало зол =) Не значит, что мне им нравятся. – JonVD 2010-11-26 14:35:00

2

В принципе, это займет много логики природы, которую вы описали. Там нет быстрого и легкого пути. Вы бы быстрее и легче выполняли этот тип манипуляций в коде бизнес-логики, а не в базе данных.

Если вы собираетесь сделать это в базе данных, рассмотрите возможность обертывания логики в функции, например this one.

0

Я могу сказать вам алгоритм, но я не уверен, как это сделать в SQL. например:

words[] = string.split(" ") 
foreach word in words 
---if(word.length<=3) //do that only for short words 
-------if(word[i]>=65 && word[i]<=90) //check the ascii code for upper case 
------------word[i] += 21; // transfer it into lower case 
---new sentence += " " + words[i] //add to the resultant string 
2

Хотя это не чистое решение SQL, другой вариант был бы определить функцию, которая преобразовала строку по желанию, может быть, назвав его REPLACE_MULTI. Заклятие было бы что-то вроде

SELECT REPLACE_MULTI('This Is An Example Of The String', 
        'Is|An|Of|The', 
        'is|an|of|the') 
    FROM DUAL; 

и реализация будет что-то вдоль линий

CREATE OR REPLACE FUNCTION REPLACE_MULTI(strOriginal   IN VARCHAR2, 
             strTokens_to_replace IN VARCHAR2, 
             strReplacement_tokens IN VARCHAR2) 
    RETURN VARCHAR2 
IS 
    strResult    VARCHAR2(2000); 
    arrTokens_to_replace DBMS_SQL.VARCHAR2A; 
    arrReplacement_tokens DBMS_SQL.VARCHAR2A; 
    i      NUMBER; 

    FUNCTION extract_tokens(p_string IN VARCHAR2, 
          p_separators IN VARCHAR2) RETURN DBMS_SQL.VARCHAR2A 
    IS 
    arrTokens DBMS_SQL.VARCHAR2A; 
    BEGIN 
    WITH sel_string AS 
     (SELECT p_string AS fullstring FROM DUAL) 
    SELECT SUBSTR(fullstring, beg + 1, end_p - beg - 1) AS token 
     BULK COLLECT INTO arrTokens 
     FROM (SELECT beg, LEAD(beg) OVER (ORDER BY beg) AS end_p, fullstring 
       FROM (SELECT beg, fullstring 
         FROM (SELECT LEVEL beg, fullstring 
           FROM sel_string 
           CONNECT BY LEVEL <= LENGTH(fullstring)) 
         WHERE INSTR(p_separators, SUBSTR(fullstring, beg, 1)) > 0 
        UNION ALL 
         SELECT 0, fullstring FROM sel_string 
        UNION ALL 
         SELECT LENGTH(fullstring) + 1, fullstring FROM sel_string)) 
     WHERE end_p IS NOT NULL AND 
      end_p > beg + 1; 

    RETURN arrTokens; 
    END extract_tokens; 

BEGIN 
    arrTokens_to_replace := extract_tokens(strTokens_to_replace, '|'); 
    arrReplacement_tokens := extract_tokens(strReplacement_tokens, '|'); 

    strResult := strOriginal; 

    FOR i IN 1..arrTokens_to_replace.COUNT LOOP 
    strResult := REGEXP_REPLACE(strResult, 
           '^' || arrTokens_to_replace(i) || ' ', 
           arrReplacement_tokens(i)); 
    strResult := REPLACE(strResult, 
         ' ' || arrTokens_to_replace(i) || ' ', 
         ' ' || arrTokens_to_replace(i) || ' '); 
    strResult := REGEXP_REPLACE(strResult, 
           ' ' || arrTokens_to_replace(i) || '$', 
           ' ' || arrReplacement_tokens(i)); 
    END LOOP; 

    RETURN strResult; 
END REPLACE_MULTI; 

я уверен, что есть символические строки, которые могут быть созданы, которые будут срывать регулярные expression- (попробуйте поставить «^» или «$» туда и посмотреть, как искры летают :-), но это достаточно хорошо для первоначального взлома.

(Кстати, процедура «extract_tokens» не моя - я нашел ее в Интернете где-то некоторое время назад и бесконечно благодарен тому, кто это сделал, что создал это).

Делитесь и наслаждайтесь.

Смежные вопросы