2017-07-09 2 views
0

Kann mir jemand helfen, mein Regex-Muster zu optimieren, damit ich nicht alle Regexes durchlaufen muss? Also stimmt es mit der ganzen Saite überein, wie das Beispiel, das ich zur Verfügung gestellt habe.Wie kann ich diesen Regex optimieren?

$pattern = "/__\(\"(.*)\"/"; 
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER); 

$pattern = "/__\(\"(.*)\",/"; 
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER); 

$pattern = "/__\(\'(.*)\'/"; 
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER); 

$pattern = "/__\(\'(.*)\',/"; 
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER); 

$pattern = "/_e\(\"(.*)\"/"; 
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER); 

$pattern = "/_e\(\"(.*)\",/"; 
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER); 

$pattern = "/_e\(\'(.*)\'/"; 
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER); 

$pattern = "/_e\(\'(.*)\',/"; 
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER); 

Beispiel:

_e('string'); 
_e("string"); 
_e('string', 'string2'); 
_e("string", 'string2'); 
__('string'); 
__("string"); 
__('string', 'string2'); 
__("string", 'string2'); 

Auch wenn es möglich ist, auch unter diese Zeichenfolge übereinstimmen.

"string"|trans 
'string'|trans 
"string"|trans({}, "string2") 
'string'|trans({}, 'string2') 
'string'|trans({}, "string2") 
"string"|trans({}, 'string2') 

Wenn es möglich ist, den Wert string2 auch zu bekommen. Im schlimmsten Fall gibt es in der Datei auch gemischte Einzel- und Doppelkurse.

Wie Sie jetzt auf meinem preg_match_all-Code sehen, gehe ich mit 8 Mustern für das erste und auch mit 8 Mustern für das zweite, um die erste Schnur zu erhalten.

Hinweis: Ich führe dieses Skript nur auf Konsolenbefehl, nicht in PHP-Anwendung. Ich achte also nicht auf die Leistung und es spielt auch keine Rolle.

Vielen Dank für Ihre Hilfe!

Edited

Vielen Dank für die Antwort. Ich habe beide deine Regex versucht, fast da. Meine Frage könnte verwirrend sein. Ich bin kein englischer Sprecher. Ich kopiere Paste von Regex101. Es ist vielleicht einfacher zu verstehen, was ich zu erreichen versuche.

https://regex101.com/r/uX5nqR/2

und dieses zu

https://regex101.com/r/Fxs7yY/1

Bitte überprüfen Sie dies. Ich habe versucht, Übersetzungen aus Wordpress-Projekt und auch Zweigdatei, die mit "Trans" Filter zu extrahieren. Ich weiß, dass es mo po Editor gibt, aber der Editor erkennt die Dateiendung, die ich verwendet habe, nicht.

Antwort

1

Ich nahm mir die Freiheit, dies in JavaScript zu schreiben, aber die Regex wird das gleiche funktionieren.

Mein vollständige Code sieht wie folgt aus:

const r = /^_[e_]\((\"(.*)\"|\'(.*)\')(, (\"(.*)\"|\'(.*)\'))?\);$/; 

const xs = [ 
    "_e('string');", 
    "_e(\"string\");", 
    "_e('string', 'string2');", 
    "_e(\"string\", 'string2');", 
    "__('string');", 
    "__(\"string\");", 
    "__('string', 'string2');", 
    "__(\"string\", 'string2');", 
]; 

xs.forEach((x) => { 
    const matches = x.match(r); 

    if(matches){ 
    console.log('matches are:\n ', matches.filter(m => m !== undefined).join('\n ')); 
    }else{ 
    console.log('no matches for', x); 
    } 
}); 

Nun lassen Sie mich erklären, wie die Regex funktioniert und wie ich es ankam: Zuerst habe ich bemerkt, dass alle Saiten mit _ und enden mit );, beginnen also wusste ich, dass die Regex so aussehen musste wie ^…\);$. Hier ^ und $ markieren Sie den Anfang und das Ende der Zeichenfolge, und Sie sollten sie auslassen, wenn sie nicht erforderlich sind.

Nach dem ersten _ Sie haben entweder einen anderen _ oder eine e, so setzen wir diese in eine Gruppe, die durch die öffnende Klammer gefolgt: [e_]\(.

Jetzt haben wir eine Zeichenfolge, die entweder in " oder in ' ist, und wir setzen es als Alternativen: (\"(.*)\"|\'(.*)\').

Diese Zeichenfolge wird wiederholt, aber optional mit einer führenden , vor. So erhalten wir (, …)? für den optionalen Teil und (\"(.*)\"|\'(.*)\') für den gesamten zweiten Teil.


für den zweiten Teil des Problems Sie die gleiche Strategie verwenden können:

"string"|trans 
'string'|trans 
"string"|trans({}, "string2") 
'string'|trans({}, 'string2') 
'string'|trans({}, "string2") 
"string"|trans({}, 'string2') 

beginnen den Aufbau Ihres regex von den Ähnlichkeiten. Wir haben das gleiche Saitenmuster wie zuvor zweimal und der optionale zweite Teil sieht nun wie folgt aus: (\(\{\}, (\"(.*)\"|\'(.*)\')\))?.

So können wir mit einem regex so enden können:

^(\"(.*)\"|\'(.*)\')\|trans\(\{\}, (\"(.*)\"|\'(.*)\')\))?$ 

Bitte beachten Sie, dass dieser regex nicht getestet, aber nur eine Vermutung von meiner Seite.


Bei der weiteren Diskussion wurde deutlich, dass wir in einem größeren Bündel von Text in mehreren Spielen suchen. Zur Anpassung an diese müssen wir die ' und " Charaktere aus den innersten Gruppen ausschließen, die uns mit diesem Regexes verläßt:

_[e_]\(("([^"]*)"|\'([^']*)\')(, ("([^"]*)"|\'([^']*)\'))?\); 
(\"(.*)\"|\'(.*)\')\|trans(\(\{\}, (\"(.*)\"|\'(.*)\')\))? 

Ich habe auch festgestellt, dass meine zweite regex offenbar eine unerreichte Klammer in sich hatte.

+0

Danke, Jakob! Ich habe versucht, deine Regex, ich denke, meine Frage war verwirrend. also habe ich das beispiel im regex tester zur verfügung gestellt. – user3392555

+0

Hey, danke für die Klarstellung. Ich habe meine Antwort mit zwei angepassten Regexes aktualisiert. –

+1

Ich dachte, ich antworte schon auf deine Antwort. Nun, ich habe es vergessen. Der erste Regex funktioniert perfekt! der zweite funktioniert noch nicht wie erwartet. Ich werde versuchen, es herauszufinden. Danke, Jakob! Das ist große Hilfe von dir ... – user3392555

0

Ich habe versucht, den Zweck dieser Regexe zu verstehen - hier ist was ich denke. (Lassen Sie mich die Schrägstriche auf beiden Seiten weglassen, auch die Zeichenfolge Anführungszeichen zu der Sprache gehört, anstelle der regulären Ausdruck selbst.)

(__|_e)\(\"(.*)\" 
(__|_e)\(\'(.*)\' 

Auf diese Weise können alle Hits Ihrer 8 Regexes oben erhalten; aber das ist wahrscheinlich nicht das, was Sie erreichen wollten.

Soweit ich verstehe, möchten Sie die I18N Refs in Ihrem Code auflisten, mit einem oder mehreren Argumenten zwischen den Klammern. Ich denke, der beste Weg, es zu tun, um eine preg_match_all mit der einfachsten Form des Musters ausgeführt wird:

(__|_e)\(.*\) 

oder vielleicht dieses ist besser:

(__|_e)\([^\)]+\)  // works for multiple calls in one line, ignores empties 

... und dann die Ergebnisse einer iterieren von ein und teilen Sie sie durch Komma:

foreach($matches as $m) { 
    $args = explode(",",$m[1]); // [1] = second subpattern 
    ; 
    ; // now you have the arguments of this function call 
    ; 
} 

Wenn diese Antwort nicht hilft, lassen Sie uns die Frage verfeinern :)

+0

Danke, dkellner! In der Tat ist es nicht das, wonach ich suche. Ich habe nur ein Beispiel gegeben. Es könnte leichter zu verstehen sein als meine Frage ..: D – user3392555