![]() |
Problem mit regulärem Ausdruck
Hallo in die Runde,
ich möchte etwaige Fehler in XMLs beheben, bevor ich diese in dem Parser lade.
Delphi-Quellcode:
Dazu nutze ich folgenden Ausdruck.
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; Die Quelle für den String ist folgende: ![]() 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 |
AW: Problem mit regulärem Ausdruck
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.
Delphi-Quellcode:
wird hier nicht unterstützt, sondern
#...
Delphi-Quellcode:
(?#...)
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. ![]() 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
Delphi-Quellcode:
, während Andere das nicht haben (z.B. TRegEx im Delphi), wo die Modifier als Enum in einem eigenen Parameter übergeben werden.
/.../x
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 ![]() 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
Delphi-Quellcode:
(eXtended).
x
|
AW: Problem mit regulärem Ausdruck
Ich habe dein Skript mal angepasst, aber ich kenne mich mit RegExp auch nicht aus.
Delphi-Quellcode:
Die eine Zeile musste ich entfernen, da sonst das Skript bei meinem Beispiel-XML einfach bei den Elementen das < entfernt hat:
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;
Code:
Ob das jetzt richtig funktioniert, weiß ich auch nicht wirklich, aber die RegExpr Klasse meckert zumindest nicht.
<?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> 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 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:29 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz