Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.140 Beiträge
 
Delphi 12 Athens
 
#2

AW: RegEx: fehlerhafter Zeilenumbruch (PostgreSQL)

  Alt 14. Jul 2016, 16: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;
  --

--
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat