Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT (https://www.delphipraxis.net/68548-regex-%3D-regex-php-ereg-liefert-immer-nur-reg_badrpt.html)

static_cast 1. Mai 2006 15:52


RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Hallo,

ich habe ein Problem mit einem RegEx und zwar möchte ich aus einem String 3 Teilstrings haben, ist ja nicht weiter wild nur jetzt wollte ich das auf der Serverseite lösen um damit noch andere Sachen anzustellen.

Der String kann "status:up@pppX", "status:waiting@pppX" oder "status:down" sein. nun hatte ich im Programm dieses RegEx verwendet: "^(.*?):(.*?)(@(.*?))?$" funktioniert aber nicht in PHP, was mache ich denn nur falsch? :(

Grüße und einen schönen ersten Mai

Ratte 1. Mai 2006 15:54

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
a) ja es gibt verschiedene Variantenfür RegEx. Was mir bei deinem Beispiel auffällt sind die (). viele RegEx benutzen stattdessen []. Probier das mal!

DGL-luke 1. Mai 2006 15:57

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
MÖP!

[] sind für Zeichenklassen, () sind zur Abgrenzung von Gruppen bzw. lookahead/lookbehind.

du solltst preg_* benutzen, die sind POSIX-konform. ereg sind afaik aber etwas schneller.

Außerdem hast du die Anfangs- und Endzeichen vergessen:

Code:
"^(.*?):(.*?)(@(.*?))?$" => "|^(.*?):(.*?)(@(.*?))?$|"
(man beachte die pipes)
EDIT: außerdem wird der für status:down nix finden.

Code:
=status:(((waiting|up)@(.*?))|down)=
Ich werd das mal kurz testen... Nein, das bringt keine befriedigenden Ergebnisse.. werde mal weiterversuchen.

static_cast 1. Mai 2006 16:08

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Hoi,

mit
Code:
preg_match("|^(.*?):(.*?)(@(.*?))?$|", $linestatus, $regs);
funktioniert es, das selbe ergebnis wie mit TRegExp.

Ist der einzige Unterschied in PHP die Pipes?

//Edit:

also bei mir gehts so

Code:
$linestatus = "status:up@ppp0";
preg_match("|^(.*?):(.*?)(@(.*?))?$|", $linestatus, $regs);
echo "1:".$regs[1]."\n"; // ist status
echo "2:".$regs[2]."\n"; // ist up
echo "3:".$regs[3]."\n"; // ist @ppp0
echo "4:".$regs[4]."\n"; // ist ppp0
Code:
$linestatus = "status:down";
preg_match("|^(.*?):(.*?)(@(.*?))?$|", $linestatus, $regs);
echo "1:".$regs[1]."\n"; // ist status
echo "2:".$regs[2]."\n"; // ist down
echo "3:".$regs[3]."\n"; // leer
echo "4:".$regs[4]."\n"; // leer
aber wenn es noch eleganter geht bin ich ganz ohr ;)

DGL-luke 1. Mai 2006 16:31

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Das sind nicht "die pipes", das sind die ausdrucksanfangs- und endzeichen. Was das für zeichen sind, ist egal. =,/,|,a,b,c... das zeichen darf dann nur inenrhalb des regex nicht mehr vorkommen.

Meine version:

Code:
<pre>
<?php
$tests = array('status:up@ppX','status:waiting@ppX','status:down');

foreach ($tests as $test)
{
  preg_match('=^(status):((.*?)@(.+)|down)$=',$test,$matches);
  print_r($matches);
  print "\n";
}
?>
</pre>
Ergebnis:

Code:
Array
(
    [0] => status:up@ppX
    [1] => status
    [2] => up@ppX
    [3] => up
    [4] => ppX
)

Array
(
    [0] => status:waiting@ppX
    [1] => status
    [2] => waiting@ppX
    [3] => waiting
    [4] => ppX
)

Array
(
    [0] => status:down
    [1] => status
    [2] => down
)
Allerdings müssste mans noch schaffen, den status (waiting/up/down) in den selben index zu schieben.

cruiser 1. Mai 2006 16:38

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
evtl. down noch mal einklammern? *hrm*

Edit: Nee, das ist Blödsinn... aber dashier:

Code:
<pre>
<?php
$tests = array('status:up@ppX','status:waiting@ppX','status:down');

foreach ($tests as $test)
{
  preg_match('=^(status):((.*?)@(.+)|down)$=',$test,$matches);
  if (count($matches) < 4) {
     $matches[3] = $matches[2];
     $matches[4] = "none";
   }
  print_r($matches);
  print "\n";
}
?>
</pre>
bringt das hier:

Code:
Array
(
    [0] => status:up@ppX
    [1] => status
    [2] => up@ppX
    [3] => up
    [4] => ppX
)

Array
(
    [0] => status:waiting@ppX
    [1] => status
    [2] => waiting@ppX
    [3] => waiting
    [4] => ppX
)

Array
(
    [0] => status:down
    [1] => status
    [2] => down
    [3] => down
    [4] => none
)

static_cast 1. Mai 2006 17:00

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Zitat:

Das sind nicht "die pipes", das sind die ausdrucksanfangs- und endzeichen. Was das für zeichen sind, ist egal. =,/,|,a,b,c... das zeichen darf dann nur inenrhalb des regex nicht mehr vorkommen.
Ahhh das muss man natürlich wissen. Aber sollte dieses Zeichen noch ein mal im RegEx gefunden werden kann ich es doch Escapen mit \ oder?

Hmmm in deiner Version das ist aber nicht gerade einfacher zu handhaben da der Status dann in verschiedenene Elementen sein kann.

Und der Status kann (im schlimmsten fall) auch noch "error" sein, sprich "status:error" deswegen ist es statisch nach down zu suchen nicht gerade von Vorteil denke ich mir mal.

DGL-luke 1. Mai 2006 17:40

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Zitat:

Zitat von DGL-luke
Allerdings müssste mans noch schaffen, den status (waiting/up/down) in den selben index zu schieben.

:zwinker:

Ja, escapen kann mans. Hier meine endgültige version, die leider etwas overhead produziert, dafür aber reines regex ist:

Code:
<pre>
<?php
$tests = array('status:up@ppX','status:waiting@ppX','status:down');

$exp = '/(?<=^status:) (((up|waiting|down)(@?)(.*?))) (?=$)/x';

foreach ($tests as $test)
{
  preg_match($exp,$test,$matches);
  print_r($matches);
  print "\n";
}
?>
</pre>
Ergebnis:

Code:
Array
(
    [0] => up@ppX
    [1] => up@ppX
    [2] => up@ppX
    [3] => up
    [4] => @
    [5] => ppX
)

Array
(
    [0] => waiting@ppX
    [1] => waiting@ppX
    [2] => waiting@ppX
    [3] => waiting
    [4] => @
    [5] => ppX
)

Array
(
    [0] => down
    [1] => down
    [2] => down
    [3] => down
    [4] =>
    [5] =>
)
Status am Index 3, Server falls vorhanden an 5.

Ich werd mal sehen, ob man da noch was rauswerfen kann.

static_cast 2. Mai 2006 00:43

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Zitat:

Zitat von DGL-luke
Zitat:

Zitat von DGL-luke
Allerdings müssste mans noch schaffen, den status (waiting/up/down) in den selben index zu schieben.

:zwinker:

Oh hab ich überlesen ;) Naja ich werd mal etwas rumtesten...

MathiasSimmack 2. Mai 2006 11:06

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Ich greife mir mal das Thema, denn ich habe auch eine Frage dazu. :stupid: Ich habe eine nette kleine Datei mit INI-ähnlichen Sektionen à la
[code=pre][bla]
...

Code:
[b]jede Menge Text[/b]

[blu]
Den markierten Teil möchte ich erkennen, herausnehmen, separat behandeln und später wieder einfügen. Die Grundlage habe ich bereits:
Code:
preg_match_all("/^\[code\](.*?)[color=red](^\[)[/color]/msi", $source, $codeParts);
Das funktioniert allerdings nur, wenn nach der markierten Sektion noch eine andere in eckigen Klammern kommt. Das ist aber kein Muss. Hier könnte auch das Dateiende sein. Was muss ich also im rot markierten Teil ergänzen, damit er sowohl eine öffnende eckige Klammer am Zeilenanfang als auch das Dateiende erkennt?

cruiser 2. Mai 2006 11:21

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Code:
(^\[|$)
Da die RegEx nicht ungreedy gesetzt ist müsst sie ja per default greedy sein, also sie viele Daten mitnehmen wie geht... also prüfst du nach dem Anfang eines neuen Block oder dem Ende der Zeile...

(ungetestet)

alcaeus 2. Mai 2006 11:25

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Hallo Matthias,

versuch mal das:
Code:
preg_match_all("/^\[code\]([^\[]*?)/msi", $source, $codeParts);
Du suchst einfach alles, was keine [ ist ;)
Du hast dann aber ein Problem, wenn eine eckige Klammer im Text vorkommt ;)

Greetz
alcaeus

MathiasSimmack 2. Mai 2006 11:25

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Zu einfach, :stupid:, den hatte ich schon. Wenn ich das ergänze, dann nimmt er auch Leerzeilen innerhalb der gesuchten Sektion als Ende, und das soll er ja nicht. Sorry, mein Fehler, :oops:, hätte ich erwähnen müssen.

@alca: Kann ich auch nicht machen, ;), da eben auch eckige Klammern innerhalb des Textes vorkommen können.

cruiser 2. Mai 2006 11:32

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Code:
preg_match_all("/^\[code\](.*)(\[?)/msi", $source, $codeParts);
Dann nimm den ;) der ist nun auch getestet ;)


/Edit: aber auch nich so richtig :/ :pale: *hrrrm*

alcaeus 2. Mai 2006 11:35

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Dann bleibt dir wohl nichts anderes uebrig, als die ersten Sektionen mit deiner Regex auszulesen, und die letzte dann anhand der Position der gefundenen Sektionen im Ursprungsstring zu bestimmen.
Das $ matcht in Multiline-Expressions naemlich immer das Zeilenende, das kannst du nicht verhindern. Von daher gibt es afair keinen gesunden Weg, das Stringende zu bestimmen ;)

Greetz
alcaeus

MathiasSimmack 2. Mai 2006 11:36

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
\Z oder \z müsste korrekt sein, wenn ich nicht irre. Zumindest funktioniert die Idee. Ich habe noch einen Bug drin, aber der hat mit einer anderen Sache zu tun :mrgreen:.

MathiasSimmack 2. Mai 2006 11:43

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Klappt. Ich habe fertig. :stupid: Ich habe gerade eine Miniklasse für einen zweiteiligen Inno Setup-Highlighter geschrieben. Der nutzt GeSHi, formatiert aber Skript- und Pascalteil separat. Darum die Auftrennung der
Zitat:

Datei mit INI-ähnlichen Sektionen
:zwinker: Es gibt nämlich einige Schlüsselworte der anderen Sektionen (FileName, usw.), die ich persönlich auch manchmal als Variablennamen in der [Code]-Sektion nutze. Und die sollten da natürlich nicht als Schlüsselwort formatiert werden.

Also, herzlichen Dank an alle Mitwürgenden. :mrgreen:

cruiser 2. Mai 2006 11:50

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
/Edit: zu viel probiert und nicht mitgelesen, vergesst es :/

MathiasSimmack 2. Mai 2006 14:57

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Wieso? Ich habe noch eine Kleinigkeit gefunden. Wenn unmittelbar hintereinander zwei [Code]-Sektionen folgen, ignoriert er die zweite. Folgen gleich drei [Code]-Sektionen aufeinander, ignoriert er die mittlere. :gruebel:

MathiasSimmack 3. Mai 2006 19:00

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Damit geht es
Code:
"/^\[code\](.*?)(^\[[^code]|\Z)/msi"
:stupid:


Jetzt benötige ich nur noch eine Möglichkeit, Kommentare und Prä-Prozessor-Anweisungen zu finden, die sich direkt am Dateianfang befinden. Das gehört aber mehr zu GeSHi. Die folgenden Zeilen werden bspw. so formatiert:
Code:
; Kommentar
[color=red]#define ISPP "bla"[/color]
Dreh ich es um, würde die ISPP-Anweisung schwarz sein, und der Kommentar gefärbt werden. Füge ich am Anfang eine Leerzeile ein, dann wird beides korrekt gefärbt. Ich schätze, dass hier irgendwo das Problem liegt:
Code:
2 => array(
   GESHI_SEARCH => '^;.*$',
   GESHI_REPLACE => '\\0',
   GESHI_MODIFIERS => 'm',
   GESHI_BEFORE => '',
   GESHI_AFTER => ''
)

btw, COMMENT_SINGLE (stellt GeSHi für Zeilenkommentare zur Verfügung) kann ich nicht nutzen. Ich habe auch nicht mehr daran gedacht, dass das Semikolon auch als Trennzeichen in den einzelnen Sektionen benutzt wird. Man hat mich daran erinnert. ;) Folglich würde alles hinter einem Semikolon als Kommentar miss-interpretiert werden.
Code:
[Files]
Source: "bla.exe"[color=green]; DestDir: "{app}"[/color]
Darum der Umweg über reguläre Ausdrücke.

cruiser 5. Mai 2006 06:29

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Zitat:

Zitat von MathiasSimmack
Damit geht es
Code:
"/^\[code\](.*?)(^\[[^code]|\Z)/msi"

puh, sicher?
Code:
(^\[[^code]|\Z)
heisst doch umschrieben:
(       beginne match
^       Zeilenanfang
\[      Zeichen: Eckige Klammer auf
[^code] keines der Zeichen c, o, d oder e (einzelnes Zeichen)
|       oder
\Z     end of subject oder Zeilenumbruch am Ende
)      beende match
das [^code] kann dir glaube zum Verhängnis werden


Was den Single-Line-Comment angeht...

[Edit #1: hier stand mal wieder Shredder, den ich vorsichtshalber entfernt hab]

Da kommt sich irgendwo irgend etwas in die Quere bei Geshi.
Ohne alles liefert:

Code:
<pre>
<?php
$source1 ='; Kommentar
#define ISPP "bla"';
$source2 ='#define ISPP "bla"
; Kommentar';

$GESHI_SEARCH = '^;.*$';
$GESHI_REPLACE = '\\0';
$GESHI_MODIFIERS = 'm';

$source1 = preg_replace("#$GESHI_SEARCH#$GESHI_MODIFIERS", "<span style='color:#f00;'>$GESHI_REPLACE</span>", $source1);
$source2 = preg_replace("#$GESHI_SEARCH#$GESHI_MODIFIERS", "<span style='color:#f00;'>$GESHI_REPLACE</span>", $source2);
echo $source1."\n\n".$source2;

?>
</pre>
Das hier:
Code:
[color=#ff0000]; Kommentar[/color]
#define ISPP "bla"

#define ISPP "bla"
[color=#ff0000]; Kommentar[/color]
[Edit #2: Ich hab noch mal dran gebastelt]

Code:
<pre>
<?php
$source1 ='; Kommentar
#define ISPP "bla"';
$source2 ='#define ISPP "bla"
; Kommentar';

$GESHI_SEARCH[] = '@^;.*$@m';
$GESHI_SEARCH[] = '@^#.*$@m';
$GESHI_REPLACE[] = "<span style='color:#090;'>\\0</span>";
$GESHI_REPLACE[] = "<span style='color:#f00;'>\\0</span>";

$source1 = preg_replace($GESHI_SEARCH, $GESHI_REPLACE, $source1);
$source2 = preg_replace($GESHI_SEARCH, $GESHI_REPLACE, $source2);
echo $source1."\n\n".$source2;

?>
</pre>
erzeugt folgendes:
Code:
[color=#009900]; Kommentar[/color]
[color=#ff0000]#define ISPP "bla"

#define ISPP "bla"[/color]
[color=#009900]; Kommentar[/color]
Wenn du also die Compiler-Statements, die am Anfang stehn IRGENDWIE overriden kannst dann leg eine ähnliche regex wie bei den singleline-omments an

Überzeugen darfst du dich hier: http://www.cruiser-dev.de/matsim.php

MathiasSimmack 5. Mai 2006 15:16

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Zitat:

Zitat von cruiser
puh, sicher?

Richtige Frage an den Falschen. :lol: Nein, bin ich nicht, da ich mich nicht wirklich mit diesen regulären Ausdrücken auskenne. Ich habe es bisher so gedeutet: Finde alles nach einer [Code]-Sektion, bis zum Dateiende, bzw. bis zu einer neuen Sektion mit eckiger Klammer am Zeilenanfang, die nicht [Code] heißt. Das Ergebnis war witzigerweise exakt so formatiert wie im Inno Setup-Editor selbst:
[code=pre][Code]

{ ... jede Menge Pascal-artiger Code ... }

[Code]

// noch mehr davon

[Files]
...

Code:
...
Deswegen dachte ich, dass ich per Zufall die Lösung gefunden hätte. :gruebel:


Zu den Kommentaren kann ich bisher nichts sagen, weil du deine PHP-Lösung selbst per "preg_replace" geschrieben hast. Problem: Ich benutze GeSHi. Darum die Array-Definition, die so an den Highlighter gegeben wird, der dann im Text nach passenden Matches sucht. Deswegen diese Namen wie GESHI_REPLACE, usw.

Na ja, wenn ich nicht vorwärts komme, dann suche ich mir einen anderen Highlighter. Irgendwo habe ich noch den Beautifer liegen. :lol:

cruiser 5. Mai 2006 15:33

Re: RegEx != RegEx? PHP ereg liefert immer nur REG_BADRPT
 
Bin mal nich so und übersetz es in dieses Array-Format (womit sicher auch nur preg_replace gefüttert wird):

Code:
2 => array(
   GESHI_SEARCH => '^;.*$',
   GESHI_REPLACE => '\\0',
   GESHI_MODIFIERS => 'm',
   GESHI_BEFORE => '<span style="color:#090;">',
   GESHI_AFTER => '</span>'
)

3 => array(
   GESHI_SEARCH => '^#.*$',
   GESHI_REPLACE => '\\0',
   GESHI_MODIFIERS => 'm',
   GESHI_BEFORE => '<span style="color:#f00;">',
   GESHI_AFTER => '</span>'
)
So müsst es GeSHi genau so formatieren, wie ich im Beispiel, gesetz dem Fall, dass dieses BEFORE / AFTER für Formatierungen ist ;)

[Edit: noch mal zum nicht code ;) ]

ersetz mal dieses:
Code:
"/^\[code\](.*?)(^\[[^code]|\Z)/msi"
durch dieses:
Code:
"/^\[code\](.*?)([\r\n]+\[(?!code)\]|\Z)/msi"
Du musst nur aufpassen dass du dir nur Match #1 also \\1 holst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:20 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