AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

RegEx Frage

Ein Thema von hansklok · begonnen am 18. Jan 2016 · letzter Beitrag vom 18. Mai 2016
Antwort Antwort
hansklok

Registriert seit: 14. Apr 2004
Ort: Karlsruhe
318 Beiträge
 
Delphi 2010 Architect
 
#1

AW: RegEx Frage

  Alt 4. Feb 2016, 02:29
Hallo,

Eine kleine Frage als Nachtrag: wie muss ich das Pattern abändern, sodass Objekt nach einer Fallentscheidung geparst wird? Wenn Objekt von @-Zeichen umgeben wird, soll es nur den Inhalt, also ohne @-Zeichen Matchen, ansonsten immer den kompletten Inhalt.

Beste Grüße
  Mit Zitat antworten Zitat
SProske

Registriert seit: 16. Feb 2015
Ort: Halle/S.
116 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#2

AW: RegEx Frage

  Alt 4. Feb 2016, 19:09
Könntest du dafür mal ein Beispiel geben, wie der String aussehen sollte und was du in welcher Gruppe matchen willst?
Sebastian

Geändert von SProske ( 4. Feb 2016 um 19:10 Uhr) Grund: Tippfehler
  Mit Zitat antworten Zitat
hansklok

Registriert seit: 14. Apr 2004
Ort: Karlsruhe
318 Beiträge
 
Delphi 2010 Architect
 
#3

AW: RegEx Frage

  Alt 4. Feb 2016, 20:16
Könntest du dafür mal ein Beispiel geben, wie der String aussehen sollte und was du in welcher Gruppe matchen willst?
Klara, gern
Also mein bisheriges patter schaut so aus:
Code:
(0|[1-9][\d]*) (?:@?((?<=@)[^@]+(?=@)|(?!@))(?:@ )?)([A-Za-z0-9_]+)( [^\n\r]*|)
Beispiele für ein Match sind:
Zitat:
1 NAME Max /Mustermann/
2 DATE 22 APR 2016
Dabei werden "Max /Mustermann/" und "22 APR 2016" durch das Teilpattern
Zitat:
( [^\n\r]*|)
gematcht. Nun gibt es aber Signalwörter wie "FAMS, CHIL oder FAMC" und wenn diese im Teilpattern
Zitat:
([A-Za-z0-9_]+)
auftauchen, dann soll das letzte Pattern nur den Inhalt der @-Zeichen parsen.
Beispiel:
Zitat:
1 FAMC @I123@ // also I123
1 FAMS @I124@ // also I124
1 CHIL @I125@ // also I125
  Mit Zitat antworten Zitat
SProske

Registriert seit: 16. Feb 2015
Ort: Halle/S.
116 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#4

AW: RegEx Frage

  Alt 4. Feb 2016, 21:02
Hast du Möglichkeit, das ganze nachzubearbeiten?

Also einfach die @s wegzudoktorn, wenn in der Gruppe davor eines der Signalwörter auftritt? Das sollte wesentlich einfacher gehen, als das Regex so anzupassen, dass die Signalwörter berücksichtigt werden und dann eine Fallunterscheidung zu machen.

Was sollte denn passieren bei:

Code:
1 NAME @Max /Mustermann/@
1 FAMC I123
1 FAMC @I123
1 FAMC I123@
1 FAMC @I@12@3@
Sebastian
  Mit Zitat antworten Zitat
hansklok

Registriert seit: 14. Apr 2004
Ort: Karlsruhe
318 Beiträge
 
Delphi 2010 Architect
 
#5

AW: RegEx Frage

  Alt 4. Feb 2016, 21:12
Hast du Möglichkeit, das ganze nachzubearbeiten?

Also einfach die @s wegzudoktorn, wenn in der Gruppe davor eines der Signalwörter auftritt? Das sollte wesentlich einfacher gehen, als das Regex so anzupassen, dass die Signalwörter berücksichtigt werden und dann eine Fallunterscheidung zu machen.

Was sollte denn passieren bei:

Code:
1 NAME @Max /Mustermann/@
1 FAMC I123
1 FAMC @I123
1 FAMC I123@
1 FAMC @I@12@3@
Es gibt einen Standard und da ist eindeutig definiert, dass nach FAMS, FAMC und CHIL ein von @-Zeichen eingeschlossener Wert folgen muss.
  Mit Zitat antworten Zitat
SProske

Registriert seit: 16. Feb 2015
Ort: Halle/S.
116 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#6

AW: RegEx Frage

  Alt 4. Feb 2016, 22:14
So langsam wird es kompliziert

Probier mal:

Code:
(0|[1-9][\d]*)\h+(?:@?((?<=@)[^@]+(?=@)|(?!@))(?:@\h+)?)(?<Special>FAM[SC]|CHIL)?(?(Special)|(?<NoSpecial>\w+))(?(Special)\h+@([^\v]*|)@|\h*([^\v]*|))
Im Prinzip prüfe ich, ob es einen deiner Specialfälle gibt, dann wird der gematcht - sonst das normale Verfahren. Und das nochmal für den Inhalt. Leider erzeugt Delphi im Match-Objekt einige eigentlich nicht vorhandene Gruppen - ich wüsste auch nicht wie ich die wegkriege. Deswegen mal zur Auswertung ein kleines Konsolenprogramm.

Zum selber durchgucken: https://regex101.com/r/gL9pX8/3

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses
  System.SysUtils, RegularExpressions;

const
  Sample = '0 @Reference@ Objekt' + sLineBreak +
           '1 NAME Max /Mustermann/' + sLineBreak +
           '2 DATE 22 APR 2016' + sLineBreak +
           '1 FAMC @I123@' + sLineBreak +
           '1 FAMS @I124@' + sLineBreak +
           '1 CHIL @I125@';
var
  Match: TMatch;
begin
  try
    Match := TRegEx.Match(Sample, '(0|[1-9][\d]*)\h+(?:@?((?<=@)[^@]+(?=@)|(?!@))(?:@\h+)?)(?<Special>FAM[SC]|CHIL)?(?(Special)|(?<NoSpecial>\w+))(?(Special)\h+@([^\v]*|)@|\h*([^\v]*|))');
    while Match.Success do
    begin
      if Match.Groups.Count = 7 then
      begin
        WriteLn('Number:' + Match.Groups[1].Value);
        WriteLn('Reference:' + Match.Groups[2].Value);
        WriteLn('Object:' + Match.Groups[4].Value);
        WriteLn('Content:' + Match.Groups[6].Value);
      end else if Match.Groups.Count = 6 then
      begin
        WriteLn('Number:' + Match.Groups[1].Value);
        WriteLn('Reference:' + Match.Groups[2].Value);
        WriteLn('Object:' + Match.Groups[3].Value);
        WriteLn('Content:' + Match.Groups[5].Value);
      end else
        WriteLn('Das ist anders :(:' + Match.Groups[0].Value);
      WriteLn('');
      Match := Match.NextMatch;
    end;
    ReadLn;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Sebastian
  Mit Zitat antworten Zitat
hansklok

Registriert seit: 14. Apr 2004
Ort: Karlsruhe
318 Beiträge
 
Delphi 2010 Architect
 
#7

AW: RegEx Frage

  Alt 5. Feb 2016, 01:22
Wow, danke! Wenn es nicht kompliziert wäre, hätte ich die Frage eh nicht ins Forum geworfen

Im Prinzip erfüllt das Pattern ja seine Sache

Also nochmal zum Aufbau:
Code:
Level (Reference) Tag (Value)
Level = Zahl 0-99
Reference = von @-Zeichen umschlossener Wert
Tag = einzelnes Wort, wobei die Wörter FAMC FAMS und CHIL eine Auswirkung auf Value, die dann ebenfalls von @-Zeichen umgeben ist haben
Value = Rest der Zeile, abhängig vom Tag

Die eingeklammerten Werte sind optional, ABER ich hätte gern immer genau 4 Match-SubStrings, also auch NIL Matches sind erlaubt. Das macht es einfacher für mich die Daten weiterzuverarbeiten.

Das Pattern
Code:
(?x)
(0|[1-9][\d]*)\h+
(?:@?((?<=@)[^@]+(?=@)|(?!@))(?:@\h+)?)
(?<Special>FAM[SC]|CHIL)?
(?(Special)|(?<NoSpecial>\w+))
(?(Special)\h+@([^\v]*|)@|\h*([^\v]*|))
hat aber bis zu 6 Match-SubStrings

Also sollte folgendes rauskommen:
Code:
1 = Level
2 = (Reference)
3 = Tag (Special/NoSpecial)
4 = Value
  Mit Zitat antworten Zitat
hansklok

Registriert seit: 14. Apr 2004
Ort: Karlsruhe
318 Beiträge
 
Delphi 2010 Architect
 
#8

AW: RegEx Frage

  Alt 17. Mai 2016, 14:33
Also, es geht darum, dass bei den drei genannten Fällen, das gematchte Ergebnis nicht getrimmt werden soll, in allen anderen Fällen schon. Ich meine also, dass alle Leerzeichen vor und nach dem Match automatisch entfernt werden. Ist das mittels RegEx möglich? Das würde mir erheblich Rechenzeit Sören, dennbisher prüfe ich dann jedes Match und führe ggf. die interne String-Trimfunktion aus. Das kostet Zeit, vor allem bei sehr langen Strings.
  Mit Zitat antworten Zitat
idefix2

Registriert seit: 17. Mär 2010
Ort: Wien
1.027 Beiträge
 
RAD-Studio 2009 Pro
 
#9

AW: RegEx Frage

  Alt 18. Mai 2016, 09:34
Naja, prinzipiell kannst du es so machen, wie ich eben beschrieben habe. Also eine Alternative zwischen "Sonderfall" und "Normalfall", wobei du im Normalfall trimmst und in den Sonderfällen nicht. Klar ist, dass du dann das Ergebnis in zwei verschiedenen Variablen erhältst, und je nachdem die eine oder die andere Variable verwenden musst. Ob aber diese Vorgangsweise insgesamt schneller ist als ein nachträgliches Trim, halte ich für sehr fraglich, die Rechenzeit für die Regex-Auswertung steigt möglicherweise stärker an als um die Zeit, die ein Trim kostet.
  Mit Zitat antworten Zitat
Antwort Antwort


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 23:49 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 by Thomas Breitkreuz