Попросили меня выполнить code-review скрипта, сгенерированного AI. Скрипт написан на PL/SQL, и выполняет следующие действия:
- во входной строке ищет и заменяет различные написания слова "строение", например "с.", "ст.", "стр-е" итп и заменяет на стандартизированное написание "стр.",
- затем разбивает полученную строку на части по набору разделителей (в данном примере это "," и ";")
- полученный набор строк дополнительно разбивается на подстроки по длине в 10 символов
Вот исходный код:
original_text VARCHAR2(4000) := 'Это строение, которое находится рядом со ст. 5; также есть стр-е в центре города. Это очень важное стро.';
modified_text VARCHAR2(4000);
chunk_size INTEGER := 10;
start_pos INTEGER := 1;
delimiter VARCHAR2(10) := ',;'; -- Разделители
current_chunk VARCHAR2(4000);
BEGIN
-- Заменяем слова
modified_text := REPLACE(original_text, 'строение', 'стр.');
modified_text := REPLACE(modified_text, 'стр-е', 'стр.');
modified_text := REPLACE(modified_text, 'стро.', 'стр.');
modified_text := REPLACE(modified_text, 'ст.', 'стр.');
DBMS_OUTPUT.PUT_LINE('Измененный текст: ' || modified_text);
-- Если строка больше 10 символов, делим ее на части
IF LENGTH(modified_text) > chunk_size THEN
-- Разделяем строку по разделителям
FOR chunk IN ( SELECT REGEXP_SUBSTR(modified_text, '[^'||delimiter||']+', 1, LEVEL) AS part FROM dual CONNECT BY REGEXP_SUBSTR(modified_text, '[^'||delimiter||']+', 1, LEVEL) IS NOT NULL ) LOOP current_chunk := TRIM(chunk.part); SELECT REGEXP_SUBSTR(modified_text, '[^'||delimiter||']+', 1, LEVEL) AS part
FROM dual
CONNECT BY REGEXP_SUBSTR(modified_text, '[^'||delimiter||']+', 1, LEVEL) IS NOT NULL
) LOOP
current_chunk := TRIM(chunk.part);
start_pos := 1; -- Делим текущую часть на подстроки по 10 символов
WHILE start_pos <= LENGTH(current_chunk) LOOP
DBMS_OUTPUT.PUT_LINE(SUBSTR(current_chunk, start_pos, chunk_size));
start_pos := start_pos + chunk_size;
END LOOP;
END LOOP;
ELSE
DBMS_OUTPUT.PUT_LINE(modified_text);
END IF;
END;
/
Казалось бы, ну чего тут такого... ну код как код, написан без особых изысков, можно сказать, что "в лоб". Но работает, ничего особо плохого сказать не могу. По ощущениям, написан программистом среднего уровня, ближе к начинающему.
А вот как можно изменить этот код, чтобы сразу было понятно, что его писал не AI и не начинающий разработчик? Вот я и задумался, а как бы написал такой код я. Вот что у меня в итоге получилось путем нескольких итераций:
original_text varchar2(4000) := 'Это строение, которое находится рядом со ст. 5; также есть стр-е в центре города. Это очень важное стро.';
modified_text varchar2(4000);
delimiter varchar2(10) := ',;'; -- разделители
begin
dbms_output.put_line('Исходный текст : ' || original_text);
-- заменяем слова
modified_text := regexp_replace(srcstr => original_text,
pattern => '(\W|^)(строение|стр-е|стро.|ст.)(\W|$)',
replacestr => '\1стр.\3',
position => 1,
occurrence => 0,
modifier => 'i');
dbms_output.put_line('Измененный текст: ' || modified_text);
-- если строка больше 10 символов, делим ее на части
for chunk in (
with q_chunks as (
select rownum rn, regexp_replace(regexp_substr(modified_text, '[^'||delimiter||']+', 1, level), '(^\s+|\s+$)', null) t
from dual
connect by level <= regexp_count(modified_text, '[^'||delimiter||']+'))
select distinct chunk.rn, level, regexp_substr(chunk.t, '.{1,'||chunk_size||'}', 1, level) t
from q_chunks chunk
connect by regexp_substr(chunk.t, '.{1,'||chunk_size||'}', 1, level) is not null
order by rn, level
) loop
dbms_output.put_line(chunk.t);
end loop;
end;
/