php-resource



Zurück   PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr > Entwicklung > PHP Developer Forum
 

Login

 
eingeloggt bleiben
star Jetzt registrieren   star Passwort vergessen
 

 

 


PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Fragen zu Laravel, YII oder anderen PHP-Frameworks.

Antwort
 
LinkBack Themen-Optionen Thema bewerten
  #1 (permalink)  
Alt 26-05-2008, 23:42
frank7l7
 Registrierter Benutzer
Links : Onlinestatus : frank7l7 ist offline
Registriert seit: Aug 2003
Beiträge: 810
frank7l7 ist zur Zeit noch ein unbeschriebenes Blatt
Standard gettext regex

Hallo mal ne frage: ich versuche das regex pattern nachzubauen mit dem auch gettext operiert, also auf strings mit _("")

derzeit hab ich

PHP-Code:
/_((?:|")([^\\1\)]+)(?:\\1\))/ 
das ist natürlich noch nicht ganz richtig ... mein problem ist wenn _("") mehrmals vorkommt. bsp:

PHP-Code:
$test "das _('ist') ein _('test')"
problem was ich hab ist das ende von ') zu finden ohne das beide platzhalter als einer gematch werden. mit [^] kann man ja nur leider zeichenklassen negieren - wie ist das wenn man einfach, anstatt einer zeichenklasse, eine zeichenkette zum negieren benutzen möchte? also bis ') das erste mal wieder vorkommt. hab mich ich das schon immer gefragt wie das geht? danke für hilfe


f*
Mit Zitat antworten
  #2 (permalink)  
Alt 26-05-2008, 23:52
Griecherus
 PHP Senior
Links : Onlinestatus : Griecherus ist offline
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
Griecherus ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Dieses Muster scheint nach meinen ersten Tests auf deine Anforderungen zu passen:
PHP-Code:
$text "das _('ist') ein _('test')";

preg_match_all('!_\\((\\'|")([^\\1)]+)\\1\\)!', $text, $matches);

echo '<pre>';
print_r($matches);
echo '</pre>';

//Array
//(
//    [0] => Array
//        (
//            [0] => _('ist')
//            [1] => _('test')
//        )
//    [1] =&gt; Array
//        (
//            [0] => '
//            [1] => '
//        )
//    [2] =&gt; Array
//        (
//            [0] => ist
//            [1] => test
//        )

Sind Erklärungen zu dem Muster nötig, oder kannst du alles nachvollziehen?

EDIT:
In solchen Fällen arbeite ich übrigens immer ganz gerne mit Named Capturing Groups, ums etwas übersichtlicher zu machen:
PHP-Code:
preg_match_all('!_\\((\\'|")(?P<gettext_value>[^\\1)]+)\\1\\)!', $text, $matches);

// zu erreichen über

$matches['gettext_value']; 
Grüße

Geändert von Griecherus (27-05-2008 um 15:51 Uhr)
Mit Zitat antworten
  #3 (permalink)  
Alt 27-05-2008, 00:11
frank7l7
 Registrierter Benutzer
Links : Onlinestatus : frank7l7 ist offline
Registriert seit: Aug 2003
Beiträge: 810
frank7l7 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Hallo, wow danke für die schnelle antwort!

so im prinzip hat mein pattern auch funktioniert problem sind aber strings wie:

PHP-Code:
$test "das _('is)t') ein _('te)st')"
mit dem ) im platzhalter ... das einfache ) muss durchgehen. hier schlagen beide patterns fehl. das ist genau das problem - es soll auf ') regieren aber ' und ) einzeln durchlassen.
Mit Zitat antworten
  #4 (permalink)  
Alt 27-05-2008, 00:22
3DMax
 PHP Senior
Links : Onlinestatus : 3DMax ist offline
Registriert seit: Jan 2004
Beiträge: 1.916
3DMax ist zur Zeit noch ein unbeschriebenes Blatt
Standard

$pattern = '/_\((\'|")(.+)\1\)/sU';

das negieren kann man sich m.m. sparen.
Mit Zitat antworten
  #5 (permalink)  
Alt 27-05-2008, 00:23
Griecherus
 PHP Senior
Links : Onlinestatus : Griecherus ist offline
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
Griecherus ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Das dürfte schon etwas komplizierter werden... Da kommt mir spontan nur eins in den Kopf: Die Regex muss erkennen, ob eine Klammer direkt auf ein Single- oder Doublequote folgt. Ist das nicht der Fall, handelt es sich nicht um die schließende Klammer des gettext-Aufrufs. Ich versuche das mal zu basteln, kann aber dauern, ich koche und bekomme noch Besuch...

Grüße
Mit Zitat antworten
  #6 (permalink)  
Alt 27-05-2008, 00:26
3DMax
 PHP Senior
Links : Onlinestatus : 3DMax ist offline
Registriert seit: Jan 2004
Beiträge: 1.916
3DMax ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Original geschrieben von Griecherus
Ich versuche das mal zu basteln, kann aber dauern, ich koche und bekomme noch Besuch...
lass dir zeit, die lösung steht schon oben
Mit Zitat antworten
  #7 (permalink)  
Alt 27-05-2008, 00:27
Griecherus
 PHP Senior
Links : Onlinestatus : Griecherus ist offline
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
Griecherus ist zur Zeit noch ein unbeschriebenes Blatt
Standard

@3DMax: Du solltest dir das Negieren nicht sparen. Zum einen greift dein Muster nicht, zum anderen arbeitest du statt der Negierung mit einem Greedy Dot. Das kann in dem Fall, dass keine Übereinstimmung gefunden wird, eine Menge mehr Performance kosten. Greedy Dots sind generell zu vermeiden, wo es geht. In diesem Fall lässt sich die Capturing Group prima durch die negierte Klasse definieren und ist damit die günstigere Lösung. Wie genau der Greedy Dot Regex-Engine intern funktioniert und wieso das im Ernstfall ungünstig ist, erkläre ich bei Bedarf gerne bei der nächst besten Gelegenheit.

Geändert von Griecherus (27-05-2008 um 00:29 Uhr)
Mit Zitat antworten
  #8 (permalink)  
Alt 27-05-2008, 00:29
3DMax
 PHP Senior
Links : Onlinestatus : 3DMax ist offline
Registriert seit: Jan 2004
Beiträge: 1.916
3DMax ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Original geschrieben von Griecherus
Zum einen greift dein Muster nicht, zum anderen arbeitest du statt der Negierung mit einem Greedy Dot. Das kann in dem Fall, dass keine Übereinstimmung gefunden wird, eine Menge mehr Performance kosten. Greedy Dots sind generell zu vermeiden, wo es geht.
also das muster greift schon.
und das mit der performance nehme ich dir auch nicht ab - das möchte ich sehen.
Mit Zitat antworten
  #9 (permalink)  
Alt 27-05-2008, 00:31
Griecherus
 PHP Senior
Links : Onlinestatus : Griecherus ist offline
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
Griecherus ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Original geschrieben von 3DMax
also das muster greift schon.
und das mit der performance nehme ich dir auch nicht ab - das möchte ich sehen.
Tut es bei mir nicht, sobald sich eine Klammer innerhalb des gettext-Strings befindest, und darum geht es dem TO. Zu deinem Zweifel: Für heute muss ich passen, aber morgen schreibe ich mal etwas dazu.

Grüße
Mit Zitat antworten
  #10 (permalink)  
Alt 27-05-2008, 00:39
3DMax
 PHP Senior
Links : Onlinestatus : 3DMax ist offline
Registriert seit: Jan 2004
Beiträge: 1.916
3DMax ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Original geschrieben von Griecherus
Tut es bei mir nicht, sobald sich eine Klammer innerhalb des gettext-Strings befindest, und darum geht es dem TO.
ohne code-tags:
EDIT:
selbst ohne code tags, werden hier die backslashes verschluckt - auf zitieren gehen, dann passt es


$test = "das _('i's)t') ein _('test')";

$pattern = '/_\((\'|")(.+)\1\)/sU';

preg_match_all($pattern, $test, $matches);

echo '<pre>'.print_r($matches, true).'</pre>';

AUSGABE:
Code:
Array
(
    [0] => Array
        (
            [0] => _('i's)t')
            [1] => _('test')
        )

    [1] => Array
        (
            [0] => '
            [1] => '
        )

    [2] => Array
        (
            [0] => i's)t
            [1] => test
        )

)
funktioniert mit klammern!

Geändert von 3DMax (27-05-2008 um 00:57 Uhr)
Mit Zitat antworten
  #11 (permalink)  
Alt 27-05-2008, 00:39
Griecherus
 PHP Senior
Links : Onlinestatus : Griecherus ist offline
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
Griecherus ist zur Zeit noch ein unbeschriebenes Blatt
Standard

So, für heute mal auf die Schnelle rausgesucht:
Repetition with Star and Plus. Das Stichwort im Zusammenhang mit dem Dot ist Backtracking. Und das ist, was die Regex unter Umständen sehr langsam werden lassen kann. Lies dir einfach mal durch, was eine Regex-Engine intern da macht.

EDIT:

Zu deinem Pattern: Jetzt klappts tatsächlich, entschuldige. Allerdings bleibe ich bei meinem Standpunkt hinsichtlich Negierter Charakterklassen versus Greedy Dots.



Grüße

Geändert von Griecherus (27-05-2008 um 00:41 Uhr)
Mit Zitat antworten
  #12 (permalink)  
Alt 27-05-2008, 00:51
3DMax
 PHP Senior
Links : Onlinestatus : 3DMax ist offline
Registriert seit: Jan 2004
Beiträge: 1.916
3DMax ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Original geschrieben von Griecherus
Das Stichwort im Zusammenhang mit dem Dot ist Backtracking. Und das ist, was die Regex unter Umständen sehr langsam werden lassen kann. Lies dir einfach mal durch, was eine Regex-Engine intern da macht.
papier und html-seiten sind geduldig
glaub ich erst, wenn ich einen benchmark gesehen habe, der signifikante unterschiede ermittelt (schreibe ich jetzt aber nicht). ansonsten sind das alles nur theoretische annahmen.

bis denne - lass es dir schmecken.

ps: um die zeit noch kochen?
Mit Zitat antworten
  #13 (permalink)  
Alt 27-05-2008, 01:21
jmc
 PHP Junior
Links : Onlinestatus : jmc ist offline
Registriert seit: Mar 2006
Beiträge: 868
jmc befindet sich auf einem aufstrebenden Ast
Standard

@Griecherus
Ich habe momentan ebenfalls keine Zeit den ganzen Regex- Code durchzusehen, aber du scheinst dich da ja sehr genau auszukennen. Kannst du statt Worten auch noch ein bisschen Code bringen?

Wenn du das nicht kannst versuch einmal mit ner Schleife die Performance zu testen - man erhält ein erstaunliches Resutat...
Mit Zitat antworten
  #14 (permalink)  
Alt 27-05-2008, 01:22
Griecherus
 PHP Senior
Links : Onlinestatus : Griecherus ist offline
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
Griecherus ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Vielleicht kann ich mich ja morgen mal dazu überreden, einen Benchmark zu schreiben... Ich verspreche aber nichts.

Ich spreche im Übrigen nicht von zwingendenden signifikanten Unterschieden beider Varianten, sondern was im Worst Case passieren sollte.
Ich denke nicht, dass der Unterschied bei zwei Mustern, die greifen, als signifikant zu bezeichnen ist. Das müsste allerdings anders aussehen, sobald die Muster keine Treffer erzielen; daher auch das Stichwort Backtracking. Spätestens jedoch bei mehreren Greedy Dots in einem einzigen Muster sind die Unterschiede signifikant (ich bin mal auf eine ModRewrite RewriteRule dieser Art gestoßen: (.*)/(.*)/(.*)/(.*), um mal ein krasses Beispiel zu nennen).

Wie gesagt, vielleicht finde ich morgen die Zeit, mal einen kleinen Benchmark zu schreiben.

OffTopic:

Danke.
Ich koche meistens um diese Zeit. Nach einem Spätdienst oder Training bleibt mir nichts anderes übrig.



Schönen Abend noch
Mit Zitat antworten
  #15 (permalink)  
Alt 27-05-2008, 15:08
Griecherus
 PHP Senior
Links : Onlinestatus : Griecherus ist offline
Registriert seit: May 2005
Ort: Berlin
Beiträge: 1.036
Griecherus ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Nochmal ein paar Worte zum Punkt Greedy Dots versus Negated Character Classes: Dazu möchte ich erklären, wie eine Regex Engine intern einen Greedy Dot abarbeitet und dadurch heraussstellen, weswegen es günstiger sein kann, nach Möglichkeit eine Negated Character Class zu benutzen. Vielleicht für diejenigen interessant, die noch nicht wussten, was da hinter den Kulissen passiert.

Ich werde die Erklärungen in Stichpunkten halten, damit kein ellenlanger Text entsteht. Ich hoffe, dass es trotzdem verständlich ist:

Beispiel Muster: /(.+)/
Beispiel Zeichenkette: /foo/bar
  • Slash aus Muster trifft auf Slash der Zeichenkette; Ergebnis: /
  • Punkt matcht alle Zeichen, zuallererst ´f´; Ergebnis /f
  • Der Punkt wird intern wiederholt, um auch das nächste Zeichen zu matchen, nun also das ´o´; Ergebnis /fo
  • Punkt wird abermals wiederholt und matcht das nächste ´o´; Ergebnis: /foo
  • Nun zum "Problem": Der Punkt trifft auf das Slash und matcht natürlich auch das, obgleich das zweite Slash in unserem Muster eigentlich das Ende des Ergebnisses demarkiert; Ergebnis: /foo/
  • Der Punkt treibt sein Spiel jetzt aber noch bis zum Ende der Zeichenkette fort, bis er beim letzten Zeichen, dem ´r´, merkt, dass das Muster fehlschlägt.
  • Erst jetzt geht die Regex Engine einen Schritt weiter und beginnt mit dem nächsten Zeichen aus dem Muster, dem zweiten Slash, das aber nichts matcht, da wir bereits am Ende der Zeichenkette angelangt sind.
  • Jetzt geht also das Backtracking los.
  • Das bisherige Ergebnis /foo/bar wird um ein Zeichen reduziert; Ergebnis: /foo/ba
  • Das reduzierte `r`passt nicht auf das aktuelle Slash des Musters, also wird weiter gebacktrackt (Copyright by Griecherus ); Ergebnis: /foo/b
  • Selbes Ergebnis wie oben - es wird weiter reduziert; Ergebnis /foo/
  • Erst jetzt greift das Slash aus dem Muster: wir haben unser gewünschtes Ergebnis. /foo/
Man sieht also, dass das Muster nur suboptimal abgearbeitet wurde, auch wenn es schlussendlich das erhoffte Ergebnis liefert.

Erste Benchmarks bei solchen Minimustern scheinen in der Tat keine signifikanten Unterschiede herauszustellen; die Ergebnisse liegen sogar ziemlich nahe beieinander. Bei komplexeren Mustern oder Mustern, die in Schleifen benutzt werden, könnte oder müsste das bereits anders aussehen - ich habe es selbst allerdings noch nicht getestet. Besonders, wenn die zu durchsuchende Zeichenkette sehr lang ist, kann man sich vorstellen, dass die Regex Engine viel Arbeit umsonst leistet, um sie nachher durchs Backtracking wieder rückgängig zu machen.
Und wenn man Ratschlag dadurch nur noch eher theoretischer Natur ist: Regex Engine intern gesehen ist es günstiger, eine Negated Character Class zu benutzen, wo sie sinnvoll eingesetzt werden kann, auch wenn man im Normalfall wohl nicht in Teufels Küche kommen wird, wenn man es nicht tut.

Ich hoffe der eine oder andere fands interessant.

Grüße

Grüße

Geändert von Griecherus (27-05-2008 um 16:16 Uhr)
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 

Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre 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 an


PHP News

ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlicht
ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlichtDie bekannte Marktplatzsoftware ebiz-trader ist in der Version 7.5.0 veröffentlicht worden.

28.05.2018 | Berni

Wissensbestand in Unternehmen
Wissensbestand in UnternehmenLebenslanges Lernen und Weiterbilden sichert Wissensbestand in Unternehmen

25.05.2018 | Berni


 

Aktuelle PHP Scripte

ADSMAN V3 - Werbe-Manager ansehen ADSMAN V3 - Werbe-Manager

ADSMAN V3 - mehr als nur ein Bannermanager! Banner, Textanzeigen und PagePeel Manager! Mit ADSMAN PRO haben Sie die Marketinglösung für eine effektive und effiziente Werbeschaltung mit messbaren Ergebnissen. Unterstützt werden Bannerformate in beliebi

25.10.2018 virtualsystem | Kategorie: PHP/ Bannerverwaltung
PHP News und Artikel Script V2

News schreiben, verwalten, veröffentlichen. Dies ist jetzt mit dem neuen PHP News & Artikel System von virtualsystem.de noch einfacher. Die integrierte Multi-User-Funktion und der WYSIWYG-Editor (MS-Office ähnliche Bedienung) ermöglichen...

25.10.2018 virtualsystem | Kategorie: PHP/ News
Top-Side Guestbook

Gästebuch auf Textbasis (kein MySQL nötig) mit Smilies, Ip Sperre (Zeit selbst einstellbar), Spamschutz, Captcha (Code-Eingabe), BB-Code, Hitcounter, Löschfunktion, Editierfunktion, Kommentarfunktion, Kürzung langer Wörter, Seiten- bzw. Blätterfunktion, V

22.10.2018 webmaster10 | Kategorie: PHP/ Gaestebuch
 Alle PHP Scripte anzeigen

Alle Zeitangaben in WEZ +2. Es ist jetzt 21:55 Uhr.