Zeichenfolge mit RegEx prüfen und ergänzen

Sea_Wave

Newbie
Registriert
Apr. 2013
Beiträge
4
Sorry:
Die Zeichenfolge : ) soll kein Smilie sein! (Wo kann ich das einstellen?)

Hallo zusammen,

seit kurzem muss ich mich mit RegEx beschäftigen.
Vielleicht bin ich hier nicht so ganz richtig, das weiß der Admin. Dafür schon mal Entschuldigung. . .

Nun stehe ich als Newbie da und muss prüfen, ob in einer Textfolge ein bestimmter Parameter gesetzt ist.
Ich bin davon ausgegangen, dass ich dieses mit ?! machen kann. Den Text / die Zeichen davor prüfe ich mit (.*), weil ich die Anzahl der Zeichen nicht kenne.
Vielleicht kann mir einer der Profis helfen. Dafür schon mal danke.
Zum Problem:

Ich habe eine Zeichenfolge, auf die ich folgende RegEx anwenden muss:
"^(http:)(.*)(?!;forum=)(.*)"

Zeichenfolge:
http://hierkönnenvieleZeichenstehen,derenLängeichnichtgenauweiß;forum=lauterZeichen;$=ZGjgV8JHkjhdqwdjkpwudn82neu8lh9jb usw

Erklärung:
^(http:) Beginn der Zeichen
(.*) alles was danach kommt; hier können beliebig viele Zeichen stehen.
(?!;forum=) wenn das da ist, soll die regex nicht zuschlagen; wenn nicht soll die RegEx etwas ergänzen (das weiß ich, das ist kein Problem für mich)
(.*) alles was danach noch kommt (kann $,=, usw sein)

Hoffentlich ist das Problem hinreichend erläutert.

Vielen Dank schon im Voraus :-)
 
Zuletzt bearbeitet:
Sea_Wave schrieb:
Die Zeichenfolge : ) soll kein Smilie sein! (Wo kann ich das einstellen?)
Einfach [noparse][/noparse] nutzen oder in [code][/code] packen.
Sea_Wave schrieb:
Hoffentlich ist das Problem hinreichend erläutert.
Mach die ?! weg, dann bekommst du folgenden Match:
Code:
array(2) {
  ["HitCount"]=>
  int(1)
  ["Hits"]=>
  array(5) {
    [0]=>
    array(1) {
      [0]=>
      string(122) "http://hierkönnenvieleZeichenstehen,derenLängeichnichtgenauweiß;forum=lauterZeichen;$=ZGjgV8JHkjhdqwdjkpwudn82neu8lh9jb"
    }
    [1]=>
    array(1) {
      [0]=>
      string(5) "http:"
    }
    [2]=>
    array(1) {
      [0]=>
      string(61) "//hierkönnenvieleZeichenstehen,derenLängeichnichtgenauweiß"
    }
    [3]=>
    array(1) {
      [0]=>
      string(7) ";forum="
    }
    [4]=>
    array(1) {
      [0]=>
      string(49) "lauterZeichen;$=ZGjgV8JHkjhdqwdjkpwudn82neu8lh9jb"
    }
  }
}
 
Sea_Wave schrieb:
...
Zum Problem:

Ich habe eine Zeichenfolge, auf die ich folgende RegEx anwenden muss:
"^(http:)(.*)(?!;forum=)(.*)"

Zeichenfolge:
http://hierkönnenvieleZeichenstehen,derenLängeichnichtgenauweiß;forum=lauterZeichen;$=ZGjgV8JHkjhdqwdjkpwudn82neu8lh9jb usw

Erklärung:
^(http:) Beginn der Zeichen
(.*) alles was danach kommt; hier können beliebig viele Zeichen stehen.
(?!;forum=) wenn das da ist, soll die regex nicht zuschlagen; wenn nicht soll die RegEx etwas ergänzen (das weiß ich, das ist kein Problem für mich)
(.*) alles was danach noch kommt (kann $,=, usw sein)
...

Erste Version war Käse - hier liegt ja eine Negation vor, das macht's unübersichtlich:

(?!;forum=) ist ein negativer lookahead, der matcht selbst nicht: d.h. er "schaut" nur ob das Token ";forum=" ab der aktuellen Position $NICHT vorkommt, und matcht dann den Rest. Insofern also schon der richtige Weg, doch Probleme ergeben sich aus der Verwendung von ".*": es wird nach $JEDEM Zeichen geprüft, ob dahinter das Token vorkommt. Wird es nach dem ersten beliebigen Zeichen nicht gefunden, schlägt die Syntax hinter der schließenden Klammer des Lookaheads aber schon wieder beim nächsten Zeichen danach zu, d.h. es wird sofort der komplette String vollständig gematcht, weil ja die Bedingung (beliebiges Zeichen nicht gefolgt von ";forum=" gefolgt von beliebigen Zeichen) sofort erfüllt ist.

Da ich nicht genau herauslesen kann, wo etwas ergänzt werden soll, und auch nicht weiß, welcher RegEx Dialekt verwendet wird, bin ich hier mit meinem Latein vorläufig am Ende.

Probiere mal EditPad Lite (free) aus, der hat 'ne ziemlich perfekte RegEx Implementation.
 
Zuletzt bearbeitet:
Hallo Xport,
danke für Deine Antwort. So etwas in die Richtung hatte ich schon vermutet; allein meine (noch) dünnen Grundlagen haben mir noch nicht den Beweis geliefert.

Zitat:
Da ich nicht genau herauslesen kann, wo etwas ergänzt werden soll, und auch nicht weiß, welcher RegEx Dialekt verwendet wird, bin ich hier mit meinem Latein vorläufig am Ende.
Zitat Ende

Dann versuche ich es nochmal zu erläutern:
Ich habe folgende Zeichenfolge:
[code)
http://hierkönnenvieleZeichenstehenderenLängeichnichtgenauweiß;forum=lauterZeichen$=ZGjgV8JHkjhdqwdjkpwudn82neu8lh9jb
[/code]
oder folgende:
[code)
http://hierkönnenvieleZeichenstehenderenLängeichnichtgenauweiß$=ZGjgV8JHkjhdqwdjkpwudn82neu8lh9jb
[/code]

Die RegEx dazu lautet:
Code:
\^(http:)(.*)(?!;forum=)(.*)\$1$2;forum=lauterZeichen$3\

Ich möchte nun beide Varianten "durch" die RegEx schieben. Im dem Fall, dass das Fragment ";forum= "nicht vorhanden ist, soll die Regex das nun einsetzen. Im anderen Fall so die RegEx die Zeichenfolgen unberührt lassen.

Ich dacht', es ist eigentlich ganz einfach. . .

Vielen Dank im Voraus für Eure Hilfe

PS: Ich teste mit regextester .com
 
So lange Du das "$=" als "Anker" sicher stellen kannst, ist es auch einfach:

Mit suchen nach "(http://.+?)(\$=)(?<!;forum=.+?\$=)(.+)$" und ersetzen durch "$1;forum=DasForum$2$3" geht es zumindest im EditPad. Andere Editoren sind beim Lookbehind allerdings empfindlicher: sie können mit unbestimmten Zeichenfolgen (.*, .+ oder .{3,9}) darin rein gar nichts anfangen.
 
Hallo und GuMo,

Zitat:
Mit suchen nach "(http://.+?)(\$=)(?<!;forum=.+?\$=)(.+)$" und ersetzen durch "$1;forum=DasForum$2$3" geht es zumindest im EditPad
Zitatende

Stimmt. Im EditPad geht es. RobRob89 hatte regexpal . com vorgeschlagen; ich selbst habe mit regextester . com gut Erfahrungen gemacht.
Beide mögen die von Dir vorgeschlagene RegEx nicht. Vor allen Dingen das "<" ist unbekannt.

Was mir auch noch nicht klar ist, ist folgendes:
Es wird gesucht nach "http usw"; dann kommt der "Anker" "$=". Wird erst danach die Abfrage gemacht, ob der String ";forum=" da ist? Das "$" am Schluss wird auch nicht gemocht. Ist das notwendig?

Danke für die Mühen.
Viele Grüße
 
Nicht alle regex Dialekte beherrschen look behinds.
Deswegen funktioniert das Pattern von Xport auch auf regextester.com nicht.

Sein Pattern macht folgendes:
Es schnappt sich erstmal alle Zeichen bis zum ersten Auftreten (--> non greedy) von "$=".
Danach wird geprüft, ob in all dem Text der bis zu diesem Punkt gecapturet (sorry für das denglisch, mir fällt kein besseres Wort ein) wurde ";forum=.+?\$=" vorkommt (--> look behind).

Das $ am Schluss gibt nur an, dass nicht übers Zeilenende hinaus geprüft werden soll.


Aber jetzt zum eigentlichen Problem:
Statt einem look behind kann man hier auch ein look ahead nutzen.

Regex Pattern:
Code:
(http://[^;]*)(;(?!forum=).*)

Replace with:
Code:
$1;forum=ABCDEFG$2

Ich bin davon ausgegangen, dass deine URLs so aussehen:
Code:
http://hierkönnenvieleZeichenstehenderenLängeichnichtgenauweiß;$=ZGjgV8JHkjhdqwdjkpwudn82neu8lh9jb
http://hierkönnenvieleZeichenstehenderenLängeichnichtgenauweiß;forum=lauterZeichen;$=ZGjgV8JHkjhdqwdjkpwudn82neu8lh9jb
Bei Zeile 1 würds einen Treffer geben und es würde dann ";forum=ABCDEFG" eingefügt werden.
Bei Zeile 2 schlägt das look ahead fehl und die URL würde unverändert bleiben.

Zur Erklärung:
Das Pattern schnappt sich zuerst alle Zeichen ungleich ";".
Dann wird geprüft ob nach dem ";" die Zeichenfolge "forum=" steht.
Wenn ja, dann ist es ein treffer.

Funktioniert so natürlich nur, wenn "forum=" immer hinter dem ersten ";" vorkommt.
Wenn "forum=" überall vorkommen kann, dann kann man noch ein ".*" davor einbauen:
Code:
(http://[^;]*)(;(?!.*forum=).*)
 
Zuletzt bearbeitet:
Hallo Grantig,

danke für die Antwort und danke für die Erläuterung :-)

Aber jetzt zum eigentlichen Problem:
Statt einem look behind kann man hier auch ein look ahead nutzen.

Ich bin noch RegEx Anfänger und dachte eigentlich, das "look behind" ist hier richtig. Dein Tip mit "look ahead" ist mir nun (auch Deiner Erläuterung) einleuchtender. Danke.

Aber:
Wenn der Schnipsel "forum=" nicht in der Zeichenfolge enthalten ist, habe ich auch kein Semikolon, sondern "nur" das "$" als (wie Xport so schön gesagt hat) als Anker.
Sieh hier:
Code:
http://hierkönnenvieleZeichenstehenderenLängeichnichtgenauweiß$=ZGjgV8JHkjhdqwdjkpwudn82neu8lh9jb

Deswegen habe ich den folgenden Code genutzt und ein wenig abgeändert:
Code:
(http://[^;]*)(;(?!.*forum=).*)

und zwar so:
Code:
(http://[^;]*)(\$(?!.*forum=).*)

Ich sage allen Beteiligten "Danke schön" für die Hilfe. Wenn Du / Ihr mir bei zukünftigen Problemen weiterhelfen könnte(s)t, wäre ich dankbar.

So, und nun muss das alles nur noch behalten werden und ich mich ggf erinnern ;-)

Und ich denke, dieser Thread kann geschlossen werden(?).
 
Zuletzt bearbeitet:
Hi,

beim nächsten mal vll. auch die Sprache mit der du arbeitest erwähnen.
 
Zurück
Oben