AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Problem mit regulärem Ausdruck

Ein Thema von Peter666 · begonnen am 28. Nov 2020 · letzter Beitrag vom 28. Nov 2020
Antwort Antwort
Peter666

Registriert seit: 11. Aug 2007
339 Beiträge
 
#1

Problem mit regulärem Ausdruck

  Alt 28. Nov 2020, 11:36
Hallo in die Runde,

ich möchte etwaige Fehler in XMLs beheben, bevor ich diese in dem Parser lade.

Delphi-Quellcode:
function CleanInvalidXmlChars(const AText: String): String;
var RegexObj: TRegExpr;
begin
  RegexObj := TRegExpr.Create;
  try
    RegexObj.Expression :=
    '[\xC0-\xC1] # Invalid UTF-8 Bytes '+
    '| [\xF5-\xFF] # Invalid UTF-8 Bytes '+
    '| [\xE0[\x80-\x9F] # Overlong encoding of prior code point'+
    '| [\xF0[\x80-\x8F] # Overlong encoding of prior code point'+
    '| [\xC2-\xDF][?![\x80-\xBF]] # Invalid UTF-8 Sequence Start'+
    '| [\xE0-\xEF][?![\x80-\xBF]{2}] # Invalid UTF-8 Sequence Start'+
    '| [\xF0-\xF4][?![\x80-\xBF]{3}] # Invalid UTF-8 Sequence Start'+
    '| [?<=[\x00-\x7F\xF5-\xFF]][\x80-\xBF] # Invalid UTF-8 Sequence Middle'+
    '| [?<![\xC2-\xDF]|[\xE0-\xEF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4]|[\xF0-\xF4][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF]{2}][\x80-\xBF]] # Overlong Sequence'+
    '| [?<=[\xE0-\xEF]][\x80-\xBF][?![\x80-\xBF]] # Short 3 byte sequence'+
    '| [?<=[\xF0-\xF4]][\x80-\xBF][?![\x80-\xBF]{2}] # Short 4 byte sequence'+
    '| [?<=[\xF0-\xF4][\x80-\xBF]][\x80-\xBF][?![\x80-\xBF]] # Short 4 byte sequence (2)';
    result := RegexObj.Replace(AText, '', true);
  finally
    RegExObj.Free;
  end;
end;
Dazu nutze ich folgenden Ausdruck.
Die Quelle für den String ist folgende: https://www.ryadel.com/en/php-skip-i...l-file-string/

Leider meckert die Regexp Bibliothek dass der "Modifier urecognized" ist. Für mich sind reguläre Ausdrücke so etwas wie böhmische Dörfer. Hat jemand vielleicht eine Idee was da falsch ist?

Peter

Geändert von Peter666 (28. Nov 2020 um 12:06 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.732 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Problem mit regulärem Ausdruck

  Alt 28. Nov 2020, 16:12
Erstmal kommt es drauf an, wass für eine Implementation der Regulären Ausdrücke du hast,
denn da unterscheiden sich einige Dinge Grundlegend, bzw. einige Sachen sind nicht überall möglich.

z.B. die Kommentare im RegEx.
#... wird hier nicht unterstützt, sondern (?#...)
und selbst wenn # als Kommentar ginge, dann fehlt dahinter der Zeilenumbruch (#10, #13#10, bzw. sLineBreak) als Ende des Kommentars, was in deinem "einen" String nicht enthalten ist.
https://regex.sorokin.engineer/de/la....html#comments
Aber hier kanns die Kommentare ja auch einfach ins Pascal/Delphi hier \\ verschieben.
Delphi kennt leider keine MultiLine-Strings, da muß man die Zeilenumbrüche eben selbst machen.

Und dann wird bei einigen Libs mit einem Start-/Ende-Zeichen gearbeitet und dahinter in den RegEx die Modifier.
Wie bei deiner Vorlage /.../x , während Andere das nicht haben (z.B. TRegEx im Delphi), wo die Modifier als Enum in einem eigenen Parameter übergeben werden.
Da hier "Modifier urecognized" als Fehler kommt, müsste für dein TRegExpr in den RegEx-String also sowas mit rein. (in die "neue" Delphi-Implementation Delphi-Referenz durchsuchenTRegEx aber nicht)

Auch Leerzeichen/Zeilenumbrüche, da kommt es auf die Konfiguration/Modifierer drauf an, ob sie "ignoriert" oder als "Suchstring" mit behandelt werden.
In den Delphiimplementationen ist eigentlich Letzteres meistens der Standardfall, außer man gibt den entsprechenden Modifier an.
Hier ist es der Modifier x (eXtended).
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu (28. Nov 2020 um 16:25 Uhr)
  Mit Zitat antworten Zitat
CHackbart

Registriert seit: 22. Okt 2012
247 Beiträge
 
#3

AW: Problem mit regulärem Ausdruck

  Alt 28. Nov 2020, 20:49
Ich habe dein Skript mal angepasst, aber ich kenne mich mit RegExp auch nicht aus.

Delphi-Quellcode:
function CleanInvalidXmlChars(const AText: string): string;
//https://www.ryadel.com/en/php-skip-invalid-characters-utf-8-xml-file-string/
var
  RegexObj: TRegExpr;
begin
  RegexObj := TRegExpr.Create;
  try
    RegexObj.Expression :=
      '[\xC0-\xC1] # Invalid UTF-8 Bytes ' + sLineBreak +
      '| [\xF5-\xFF] # Invalid UTF-8 Bytes ' + sLineBreak +
      '| [\xE0[\x80-\x9F] # Overlong encoding of prior code point' + sLineBreak +
      '| [\xF0[\x80-\x8F] # Overlong encoding of prior code point' + sLineBreak +
      '| [\xC2-\xDF][?![\x80-\xBF]] # Invalid UTF-8 Sequence Start' + sLineBreak +
      '| [\xE0-\xEF][?![\x80-\xBF]{2}] # Invalid UTF-8 Sequence Start' + sLineBreak +
      '| [\xF0-\xF4][?![\x80-\xBF]{3}] # Invalid UTF-8 Sequence Start' + sLineBreak +
      '| [?<=[\x00-\x7F\xF5-\xFF]][\x80-\xBF] # Invalid UTF-8 Sequence Middle' + sLineBreak +
   // '| [?<![\xC2-\xDF]|[\xE0-\xEF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4]|[\xF0-\xF4][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF]{2}][\x80-\xBF] # Overlong Sequence' + sLineBreak +
      '| [?<=[\xE0-\xEF]][\x80-\xBF][?![\x80-\xBF]] # Short 3 byte sequence' + sLineBreak +
      '| [?<=[\xF0-\xF4]][\x80-\xBF][?![\x80-\xBF]{2}] # Short 4 byte sequence' + sLineBreak +
      '| [?<=[\xF0-\xF4][\x80-\xBF]][\x80-\xBF][?![\x80-\xBF]] # Short 4 byte sequence (2)';
    Result := RegexObj.Replace(AText, '', True);
  finally
    RegExObj.Free;
  end;
end;
Die eine Zeile musste ich entfernen, da sonst das Skript bei meinem Beispiel-XML einfach bei den Elementen das < entfernt hat:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<Content xmlns="tag:atsc.org,2016:XMLSchemas/ATSC3/SA/1.0/"
         id="bcast://trivenidigital.com/Content961747"
         version="4">
   <ServiceReference idRef="bcast://trivenidigital.com/Service149"/>
   <Name text="Como dice el dicho"/>
   <Description text="Cada historia da inicio cuando la primera parte del dicho es escrita en una de las paredes del café, sea por Tomás, sea por Isabel, o por algún cliente."/>
   <ContentAdvisoryRatings>
      <RegionIdentifier>1</RegionIdentifier>
      <RatingDescription>TV-14</RatingDescription>
      <RatingDimensions>1</RatingDimensions>
      <RatingDimVal>
         <RatingDimension>0</RatingDimension>
         <RatingValueString>TV-14</RatingValueString>
      </RatingDimVal>
   </ContentAdvisoryRatings>
   <PrivateExt>
      <Components>
         <AudioComponent xml:lang="spa">Unspecified</AudioComponent>
      </Components>
   </PrivateExt>
</Content>
Ob das jetzt richtig funktioniert, weiß ich auch nicht wirklich, aber die RegExpr Klasse meckert zumindest nicht.
Ich gebe Himitsu Recht, Linebreaks müssen da rein, sonst sollte ab dem ersten Kommentar eigentlich alles dahinter liegende deaktiviert sein. Ist es zumindest in der bei Lazarus beiliegenden Regexpr Version aber kurioserweise nicht.

Christian

Geändert von CHackbart (28. Nov 2020 um 20:56 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:33 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf