Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Как оставить только один пробел между словами  [new]
NNN2
Guest
Есть тадлица, в которой есть колонка "Полное имя"
Там такие значения: "Иван Иванкин Иванович"
Нужно получить:"Иван Иванкин Иванович"
количество пробелов между словами может быть разным, но в результате должен быть только 1 пробел

Как?
22 апр 04, 12:26    [643021]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
denm
Member

Откуда: { empty }
Сообщений: 2792
Самый простой вариант - несколько вложенных реплейсов:

replace(replace(replace(str,'   ',' '),'  ',' '),'  ',' ')
22 апр 04, 12:31    [643037]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
AndRey Smith
Member

Откуда: г. Владимир
Сообщений: 116
заменяй два пробела на один

SQL> select replace ('ttt ttt', ' ',' ') from dual;

REPLACE
-------
ttt ttt

SQL>
22 апр 04, 12:33    [643046]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
NNN2
Guest
А если пробелов будет 27
1. Записывать несколько replace подряд не удобно.
2. а заменять 2 пробела на 1. при 27 пробелах остается 2 пробела
22 апр 04, 12:36    [643059]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
sataneyeff
Member

Откуда: Киев-Москва
Сообщений: 107
declare
str varchar2(255) := ' dsfdsf dsfdsf';
begin
while instr(str,' ')>0 loop
str := replace(str, ' ', ' ');
end loop;
str := trim(str);
dbms_output.put_line(str);
end;
22 апр 04, 12:41    [643074]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
Alty
Member

Откуда:
Сообщений: 68
Я бы написал функцию, которая по циклу на кол-во символов проверяет текущую и предыдущую букву и отсылает в новую переменную для возврата
22 апр 04, 12:41    [643076]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
sataneyeff
Member

Откуда: Киев-Москва
Сообщений: 107
declare

str varchar2(255) := ' dsfdsf dsfdsf';
begin
while instr(str,' ')>;0 loop
str := replace(str, ' ', ' ');
end loop;
str := trim(str);
dbms_output.put_line(str);
end;

так точнее, в предыдущем пробелы скушались
22 апр 04, 12:44    [643088]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
AndRey Smith
Member

Откуда: г. Владимир
Сообщений: 116
> 2. а заменять 2 пробела на 1. при 27 пробелах остается 2 пробел

два реплейса напиши один в другом ..но меняй так же два на один
и обязательно сообщи о результатах - что из всего посоветованного будет быстрее работать
22 апр 04, 12:45    [643093]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
Scott Tiger
Member

Откуда: вмваре
Сообщений: 6876
Напиши процедурку на Java с использованием java.util.StringTokenizer.
22 апр 04, 12:45    [643094]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
AndRey Smith
Member

Откуда: г. Владимир
Сообщений: 116
2 sataneyeff
предпологаю что replace
уже содержит такую проверку instr(str,' ')>;0
22 апр 04, 12:58    [643137]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
denm
Member

Откуда: { empty }
Сообщений: 2792
REGEXP - отлично подходит для таких задач (сложные замены, форматы, шаблоны и т.д.), но приличная поддержка этого появилась только в 10g http://otn.oracle.com/oramag/webcolumns/2003/techarticles/rischert_regexp_pt1.html

автор
два реплейса напиши один в другом ..но меняй так же два на один


SQL>select replace(replace('x         x','  ',' '),'  ',' ') x from dual;


X
-----

x x
22 апр 04, 13:03    [643158]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
sataneyeff
Member

Откуда: Киев-Москва
Сообщений: 107
instr для цикла нужен, если нужно более одной замены
22 апр 04, 13:07    [643173]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
Violina
Member

Откуда: Санкт-Петербург
Сообщений: 3662
create table t17(name varchar2(30));
insert into t17 values ('aa    bb         cc');
insert into t17 values ('aa  bb  cc');
insert into t17 values ('aa           bb             cc');
commit;

select
replace(replace(replace(name, ' ', ' _'), '_ '), '_') d
from t17;

D
------------------------

aa bb cc
aa bb cc
aa bb cc

В качестве символа '_' нужно взять тот, который точно не используется, например chr(0) итп.
22 апр 04, 13:25    [643244]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
Violina
Member

Откуда: Санкт-Петербург
Сообщений: 3662
Возможно кому будет интересно, как я нашла это решение, идея думаю понятна.

SQL> select replace('aa    bb         cc', ' ', ' _') d from dual;

D
--------------------------------

aa _ _ _ _bb _ _ _ _ _ _ _ _ _cc

SQL> select
  2  replace(replace('aa    bb         cc', ' ', ' _'), '_ ') d
  3  from dual;

D
----------

aa _bb _cc
22 апр 04, 13:27    [643260]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
sataneyeff
Member

Откуда: Киев-Москва
Сообщений: 107
2Виолина: супер!!!
22 апр 04, 13:32    [643284]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
denm
Member

Откуда: { empty }
Сообщений: 2792
2 Violina

Гениальное решение :)
Лучше и не придумаешь.
22 апр 04, 13:32    [643287]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
Случайный Прoхожий
Guest
Насчет написания фунции на PL/SQL или Java

Том Кайт(с), Книга 1

- если можно, сделай это с помощью одного оператора SQL
- если это невозможно, сделай это в PL/SQL
- если это невозможно в PL/SQL, сделай это с помощью Java
- если это невозможно с помощью Java, сделай внешнюю процедуру на С
- если и это невозможно, надо серъезно подумать зачем это вообще нужно

2 Виолина

Маладес! Следуюшь заветам великого Гуру.
22 апр 04, 13:35    [643295]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
Alty
Member

Откуда:
Сообщений: 68
Пробовал так, вроде все дупликаты режет
select
ltrim(rtrim(replace(replace(replace(' aa bb cc ', ' ', ' _'), '_ '),'_'))) d
from dual;
22 апр 04, 13:54    [643367]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
AndRey Smith
Member

Откуда: г. Владимир
Сообщений: 116
Violina Rulezzz!

а что я хотел сделать, до сих пор не понял :) пардон
22 апр 04, 14:02    [643394]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
AndRey Smith
Member

Откуда: г. Владимир
Сообщений: 116
а если менять два на ничто а потом снова два на ничто ?
1* select replace(replace('x x',' '),' ') x from dual
SQL> /

X
---
x x
22 апр 04, 14:25    [643482]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
AndRey Smith
Member

Откуда: г. Владимир
Сообщений: 116
SQL> select replace('Иванов Иван Иванович Сидоров', ' ') from dual;

REPLACE('ИВАНОВИВАНИВАНОВИЧС
----------------------------
Иванов Иван Иванович Сидоров
22 апр 04, 14:28    [643493]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
AndRey Smith
Member

Откуда: г. Владимир
Сообщений: 116
опять ни попал :(

SQL> select replace('Иванов Иван', ' ') from dual;

REPLACE('И
----------
ИвановИван
22 апр 04, 14:31    [643506]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
Jajahama
Member

Откуда: Москва
Сообщений: 247
2 Violina

действительно, красивое решение... можно узнать, как оно родилось?
22 апр 04, 15:06    [643628]     Ответить | Цитировать Сообщить модератору
 Re: Как оставить только один пробел между словами  [new]
Violina
Member

Откуда: Санкт-Петербург
Сообщений: 3662
to Jajahama

Я в свое время много программировала для парсинга и форматирования текстов на Си++ без использования сторонних бибилотек, и приходилось писать в том числе и некий суррогат регулярных выражений. Вот опыт пригождается.
22 апр 04, 15:37    [643755]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Как оставить только один пробел между словами  [new]
Al_vrn
Member

Откуда:
Сообщений: 101
SQL> create table t17(name  varchar2(4000));

Table created.

SQL> begin
  2    insert into t17 
  3    values (RPAD('a', (2)) || 'a');
  4    insert into t17 
  5    values (RPAD('b', (3)) || 'b');
  6    insert into t17 
  7    values (RPAD('c', (4)) || 'c');
  8    insert into t17 
  9    values (RPAD('d', (2000)) || 'd');
 10    insert into t17 
 11    values (RPAD('e', (2001)) || 'e');
 12    insert into t17 
 13    values (RPAD('f', (3999)) || 'f');
 14  end;
 15  /

PL/SQL procedure successfully completed.

SQL> select replace(replace(replace(name, ' ', ' _'), '_ '), '_') d
  2  from t17;

D
--------------------------------------------------------------------------------
a a
b b
c c
d d
e
f

6 rows selected.

SQL> select replace(
  2          replace(
  3           replace(
  4            replace(
  5             replace(
  6              replace(
  7               replace(name, '        ', ' '), 
  8                              '       ', ' '), 
  9                               '      ', ' '), 
 10                                '     ', ' '), 
 11                                 '    ', ' '), 
 12                                  '   ', ' '), 
 13                                   '  ', ' ') d
 14  from t17;

D
--------------------------------------------------------------------------------
a a
b b
c c
d d
e e
f f

6 rows selected.

Обработки до 8 пробелов достатчно, т.к. (7*203+5) < 3998 < (8*1420+6)
Проверял так:

declare
  v_str1    varchar2(4000);
  v_str2    varchar2(4000);
  v_length  number;
begin
  dbms_output.put_line('started8');
  for i in 1..3998 loop
    v_str1 := RPAD('a', (i+1)) || 'b';
    select replace(
            replace(
             replace(
              replace(
               replace(
                replace(
                 replace(v_str1, '        ', ' '), 
                                  '       ', ' '), 
                                   '      ', ' '), 
                                    '     ', ' '), 
                                     '    ', ' '), 
                                      '   ', ' '), 
                                       '  ', ' ')
    into v_str2
    from DUAL;
    if v_str2 <> 'a b' then
      dbms_output.put_line(v_str2 || '/' || i);
    end if;
  end loop;
  dbms_output.put_line('finished');
end;
26 янв 07, 10:06    [3697181]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Oracle Ответить