Tonii: Regulärer Ausdruck gesucht

Moin,

erstmal was Allgemeines. Sind reguläre Ausdrücke in allen Scriptsprachen gleich oder ähnlich?
Kommt mir so vor, als seien die alle an Perl ausgerichtet, ist aber nur ne Vermutung, deshalb frag ich.

Zur Frage:

Wenn ich in einem Text die Zeilen zeilenweise durchsuche und die Zeile des Musters

[Tab oder Leerzeichen oder beides]Kunde123[Leerzeichen]50666[Leerzeichen]Köln

identifiziere und möchte durch eine Replace-Anwendung der entsprechenden Scriptsprache ausschließlich "Kunde123" erhalten, wie müßte dann z.B meine str_replace-Zeile in php heißen?

Zu bedenken ist, daß es ja auch Kunden mit anderer PLZ in Köln gibt, sowie, daß es Kunden mit dem String "Köln" im Namen geben könnte, also z.B. der Kunde "Kölner Baustoffe" oder sowas...

Grüße, Toni

  1. Hallo Tonii.

    erstmal was Allgemeines. Sind reguläre Ausdrücke in allen Scriptsprachen gleich oder ähnlich?

    Ähnlich.

    Kommt mir so vor, als seien die alle an Perl ausgerichtet, ist aber nur ne Vermutung, deshalb frag ich.

    Nicht genau an Perl, sondern an den PCRE.

    Wenn ich in einem Text die Zeilen zeilenweise durchsuche und die Zeile des Musters

    [Tab oder Leerzeichen oder beides]Kunde123[Leerzeichen]50666[Leerzeichen]Köln

    identifiziere und möchte durch eine Replace-Anwendung der entsprechenden Scriptsprache ausschließlich "Kunde123" erhalten, wie müßte dann z.B meine str_replace-Zeile in php heißen?

    Sprachst du nicht eben noch von regulären Ausdrücken? Mit str_replace ersetzt du jedoch, wie der Name bereits impliziert, lediglich Strings durch Strings. Wenn du dich auf Stringfunktionen beschränken möchtest, eignet sich str_replace hier eher weniger.

    Besser geeignet wären strrpos, strpos, sowie substr. Mit ersterem kannst du rückläufig bis zum letzten (im String also ersten, vor „Kunde123“) Vorkommen von Leerzeichen/Tabulatoren suchen; das ist dein Startindex. Mit strpos suchst du das zweite Vorkommen (somit also nach „Kunde123“). Diese beiden Werte kannst du nun nutzen, um die Länge der ermittelten Teilzeichenkette zu ermitteln, womit du die beiden erforderlichen Argumente für substr hast.

    Solltest du einen regulären Ausdruck verwenden wollen, bietet sich preg_replace zum Beispiel mit folgendem Muster an:

    ![ \t]+([^ \t]+).*!i

    Erläuterung:

    [ \t]+    - Ein oder beliebig viele Leerzeichen/Tabulatoren
    ([^ \t]+) - Ein oder beliebig viele Zeichen AUSSER Leerzeichen/Tabulatoren, gekapselt
    .*        - Irgendetwas, beliebig oft

    Einen schönen Samstag noch.

    Gruß, Mathias

    --
    ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
    debian/rules
    1. gudn tach!

      ![ \t+([^ \t]+).*!i]

      Erläuterung:

      [ \t]+    - Ein oder beliebig viele Leerzeichen/Tabulatoren

      (ich weiss zwar, dass du's weisst, aber)
      genauer: ein oder _mehr_ leerzeichen/tabulator(en)

      ([^ \t]+) - Ein oder beliebig viele Zeichen AUSSER Leerzeichen/Tabulatoren, gekapselt

      auch hier nicht beliebig viele, sondern mind. eins.

      .*        - Irgendetwas, beliebig oft

      also hier ueberfluessig; ebenso uebrigens der i-modifier, der case-insensitivity bedeutet.

      bliebe also noch
        /[ \t]+([^ \t]+)/
      wobei sich das noch auf
        /([^ \t]+)/
      reduzieren liesse, wenn alle durchsuchten strings eh immer mit space oder tab beginnen.

      sobald der kundenname allerdings leerzeichen enthalten darf, waere es imho sinnvoll, die plz als orientierungshilfe/fixpunkt einzubeziehen, also

      /[1]+(.+?) \d{5} /

      oder mit expliziterer kundennamensvorgabe a la

      /[2]+([a-zA-Z0-9_ ]+?) \d{5} /

      prost
      seth


      1. \t ↩︎

      2. \t ↩︎

      1. gudn tach!

        .*        - Irgendetwas, beliebig oft

        also hier ueberfluessig;

        moep! sorry, hab nicht richtig gelesen. wenn beim suchen _und_ _ersetzen_ ist es nicht ueberfluessig.

        prost
        seth

      2. Hallo seth.

        ![ \t+([^ \t]+).*!i]

        Erläuterung:

        [ \t]+    - Ein oder beliebig viele Leerzeichen/Tabulatoren

        (ich weiss zwar, dass du's weisst, aber)
        genauer: ein oder _mehr_ leerzeichen/tabulator(en)

        Äh, ja. Den versteckten Widerspruch hast du gut aufgespürt. Dafür gibt es ein Bie[nr]chen.

        Einen schönen Samstag noch.

        Gruß, Mathias

        --
        ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
        debian/rules
  2. Hallo Toni,

    erstmal was Allgemeines. Sind reguläre Ausdrücke in allen Scriptsprachen gleich oder ähnlich?

    Es gibt verschiedene Systeme regulärer Ausdrücke, die häufigstens sind perl-kompatible reguläre Ausdrücke (PCRE) und reguläre Ausdrücke nach POSIX (in PHP durch die ereg-Funktionen verwendbar).

    Wenn ich in einem Text die Zeilen zeilenweise durchsuche und die Zeile des Musters

    [Tab oder Leerzeichen oder beides]Kunde123[Leerzeichen]50666[Leerzeichen]Köln

    identifiziere und möchte durch eine Replace-Anwendung der entsprechenden Scriptsprache ausschließlich "Kunde123" erhalten, wie müßte dann z.B meine str_replace-Zeile in php heißen?

    Mit str_replace() kommst du hier wahrscheinlich nicht weiter, da musst du schon preg_replace() zur Hilfe nehmen.

    Zu bedenken ist, daß es ja auch Kunden mit anderer PLZ in Köln gibt, sowie, daß es Kunden mit dem String "Köln" im Namen geben könnte, also z.B. der Kunde "Kölner Baustoffe" oder sowas...

    Willst du jede Zeile durch den Namen des Kunden ersetzen?

    preg_replace('/^(?: |\t| \t|\t )([^ ]+) \d{5} .+$/', "$1", $zeile);

    (?: |\t| \t|\t ) matcht entweder _ein_ Leerzeichen oder _einen_ Tabulator, oder ein Leerzeichen und einen Tabulator oder einen Tabulator und ein Leerzeichen. ?: sagt dem Parser, dass er sich den Ausdruck in der Klammer nicht merken soll.

    Vermutlich willst du stattdessen sowas wie [ \t]+, dies passt auf eine beliebig lange Folge von Leerzeichen und Tabulatoren, mindestens aber ein Leerzeichen oder ein Tabulator.

    ([^ ]+) steht für eine beliebige Anzahl von Zeichen, die kein Leerzeichen sind; es muss aber mindestens ein solches Zeichen an dieser Stelle vorkommen. Die Klammerung bedeutet, dass sich der Parser den durch dieses Muster bezeichneten String merkt.

    \d{5} bezeichnet genau fünf hintereinanderfolgende Ziffern (0-9)
    .+ eine beliebige Anzahl (jedoch mindestens eins) beliebiger Zeichen.

    Durch ^ am Anfang und $ am Ende wird ausgedrückt, dass das Muster auf die komplette Zeile zutreffen muss. Bei der Ersetzung wird mit "$1" auf den String der zweiten Klammer, in diesem Falle ja der Name des Kunden, zurückgegriffen (da die erste Klammer mit ?: ignoriert wird, ist die zweite für den Parser sozusagen die erste Klammer ;-) Deswegen $1 statt $2).

    Schöne Grüße,

    Johannes