Online
Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
Delphi 12 Athens
|
AW: RegEx: fehlerhafter Zeilenumbruch (PostgreSQL)
14. Jul 2016, 17:18
Hab zwar immernoch keine Ahnung, was das Problem ist , aber zumindestens hab ich erstmal wider eine funktionierende Version.
SQL-Code:
-- INI-TEXT und StringList-TEXT (Name=Value) in der DB behandeln
-- line = SL_GetLine (list, index)
-- value = SL_GetValue(list, name, [defvalue])
-- list = SL_SetValue(list, name, value, [defvalue])
-- value = INI_GetValue(ini, section, name, [defvalue])
-- ini = INI_SetValue(ini, section, name, value, [defvalue])
-- Initial : SELECT SetSetting('Test', 'aaa=nee\r\nbbb=ok\r\nccc=nee'), SetSetting('Test2', '[zzz]\r\nbbb=nee\r\n[xxx]\r\naaa=nee\r\nbbb=ok\r\nccc=nee')
-- SL-Test : SELECT GetTextSetting('Test'), SL_GetValue(GetSetting('Test'), 'bbb'), SL_SetValue(GetSetting('Test'), 'bbb', 'NEU'), SL_SetValue(GetSetting('Test'), 'bbc', 'NEU')
-- SL-Test2 : SELECT GetTextSetting('Test'), SL_GetLine(GetSetting('Test'), 1), SL_GetLine(GetSetting('Test'), 3), SL_GetLine(GetSetting('Test'), 4)
-- INI-Test : SELECT GetTextSetting('Test2'), INI_GetValue(GetSetting('Test2'), 'xxx', 'bbb'), INI_SetValue(GetSetting('Test2'), 'xxx', 'bbb', 'NEU'), INI_SetValue(GetSetting('Test2'), 'xxx', 'bbc', 'NEU')
-- Zeile aus einem StringList-TEXT auslesen
CREATE OR REPLACE FUNCTION SL_GetLine(list TEXT, line INTEGER) RETURNS VARCHAR AS $$
--SELECT (regexp_matches(list, '^(.*)$', 'm'))[line]
SELECT (regexp_split_to_array(list, ' \\r?\\n'))[line]
$$ LANGUAGE SQL IMMUTABLE;
--
-- Value aus einem StringList-TEXT auslesen -> Name=Value
CREATE OR REPLACE FUNCTION SL_GetValue(list TEXT, name VARCHAR, defvalue VARCHAR DEFAULT ' ') RETURNS VARCHAR AS $$
-- SELECT+regexp_matches liefert "keinen" Datensatz, wenn nichts gefunden wurde, daher das SUBSELECT mit COALESCE
SELECT coalesce(( SELECT (regexp_matches(list, ' ^' || name || ' =(.*)$', ' mi'))[1]), defvalue)
$$ LANGUAGE SQL IMMUTABLE;
--
-- Value in einem StringList-TEXT ändern -> Name=Value
CREATE OR REPLACE FUNCTION SL_SetValue(list TEXT, name VARCHAR, value VARCHAR, defvalue VARCHAR DEFAULT ' ') RETURNS TEXT AS $$
BEGIN
-- altes weg
list := regexp_replace(list, ' ^' || name || ' =(.*)$', ' ', ' mi');
-- neues rein
IF (value <> ' ') and (value IS DISTINCT FROM defvalue) THEN
list := concat(list, ' \r\n', name, ' =', value);
END IF;
-- sortieren
RETURN trim(array_to_string(ARRAY( SELECT regexp_split_to_table(list, ' \r?\n' , ' mi') ORDER BY 1), ' \r\n'), ' \r\n');
END $$ LANGUAGE plpgsql;
--
-- Value aus einem INI-TEXT auslesen -> [Section] Name=Value
CREATE OR REPLACE FUNCTION INI_GetValue(ini TEXT, section VARCHAR, name VARCHAR, defvalue VARCHAR DEFAULT ' ') RETURNS VARCHAR AS $$
-- SELECT+regexp_matches liefert "keinen" Datensatz, wenn nichts gefunden wurde, daher das SUBSELECT mit COALESCE
--SELECT coalesce((SELECT (regexp_matches(ini, '^\\[' || section || '\\]\\s*$[^\\[]*^' || name || '=(.*)$', 'mi'))[1]), defvalue)
-- Aus unerfindlichen Gründen funktioniert das Zeilenendematching nicht mehr, daher manuell die Zeilenumbrüche suchen http://www.delphipraxis.net/189708-regex-fehlerhafter-zeilenumbruch-postgresql.html
SELECT coalesce(( SELECT (regexp_matches(' \\n' || ini || ' \\n', ' \\r?\\n\\[' || section || ' \\][ \\t]*\\r?\\n?[^\\[]*\\r?\\n' || name || ' =([^\\r\\n]*)\\r?\\n', ' i'))[1]), defvalue)
$$ LANGUAGE SQL IMMUTABLE;
--
-- Value in einem INI-TEXT ändern -> [Section] Name=Value
CREATE OR REPLACE FUNCTION INI_SetValue(ini TEXT, section VARCHAR, name VARCHAR, value VARCHAR, defvalue VARCHAR DEFAULT ' ') RETURNS TEXT AS $$
DECLARE seA TEXT;
seN TEXT;
BEGIN
/*
-- altes weg ... der Lookbehind will nicht, wie er soll, also zuerst Section extrahieren und dann darin den Value entferen
--ini := regexp_replace(ini, '(?<!^\\[' || section || '\\]\\s*$[^\\[]*)^' || name || '=(.*)$', '', 'mi');
seA := (regexp_matches(ini, '^(\\[' || section || '\\]\\s*$[^\\[]*^' || name || '=.*)$', 'mi'))[0];
seN := regexp_replace(seA, '^' || name || '=.*$', '', 'mi');
IF seA <> '' THEN
ini := replace(ini, seA, seN);
END IF;
-- neues rein
IF regexp_matches(ini, '^\\[' || section || '\\]\\s*$', 'mi') IS NOT NULL THEN
ELSE
ini := concat(ini, '\r\n[', section, ']');
END IF;
IF (value <> '') and (value IS DISTINCT FROM defvalue) THEN
ini := regexp_replace(ini, '^\\[' || section || '\\]\\s*$', concat('[', section, ']\r\n', name, '=', value), 'mi');
END IF;
-- fertig
RETURN trim(regexp_replace(ini, '\\r?\\n([ \\t]*\\r?\\n)+', '\r\n', ''), ' \r\n');
*/
-- Aus unerfindlichen Gründen funktioniert das Zeilenendematching nicht mehr, daher manuell die Zeilenumbrüche suchen http://www.delphipraxis.net/189708-regex-fehlerhafter-zeilenumbruch-postgresql.html
ini := ' \n' || ini || ' \n';
-- altes weg
seA := (regexp_matches(ini, ' (\\r?\\n\\[' || section || ' \\][ \\t]*\\r?\\n?[^\\[]*\\r?\\n' || name || ' =([^\\r\\n]*)\\r?\\n)', ' i'))[1];
seN := regexp_replace(seA, ' ^' || name || ' =.*$', ' ', ' mi');
IF seA <> ' ' THEN
ini := replace(ini, seA, seN);
END IF;
-- neues rein
IF regexp_matches(ini, ' \\r?\\n\\[' || section || ' \\][ \\t]*\\r?\\n', ' i') IS NOT NULL THEN
ELSE
ini := concat(ini, ' \r\n[', section, ' ]\r\n');
END IF;
IF (value <> ' ') and (value IS DISTINCT FROM defvalue) THEN
ini := regexp_replace(ini, ' \\r?\\n\\[' || section || ' \\][ \\t]*\\r?\\n', concat(' \r\n[', section, ' ]\r\n', name, ' =', value, ' \r\n'), ' i');
END IF;
-- fertig
RETURN trim(regexp_replace(ini, ' \\r?\\n([ \\t]*\\r?\\n)+', ' \r\n', ' '), ' \r\n');
END $$ LANGUAGE plpgsql;
--
--
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
|