Seite 1 von 1

Mal wieder REGEX

Verfasst: 02.05.2021 17:23
von mad-manne
Hallo zusammen,
ich mal wieder mit einer REGEX-Frage :D

Ich durchsuche Zeilen eines Scripts, um dort genutzt Funktionsaufrufe für lokalisierte Termini zu finden und diese zu extrahieren.
Diese Aufrufe sehen immer so aus

Code: Alles auswählen

LEERZEICHEN + t('Hier steht dann beliebiger Text, den ich finden will .... bis hier >')
Ich will also den Text zwischen den Hochkommata(ergo den Parameter) des Funktionsaufrufs der Funktion t
Das klappt auch schon mit dieser REGEX:

Code: Alles auswählen

(?<=t\(')(.*)(?='\))
In diesem Beispiel wird Language-string I want to extract gefunden:

Code: Alles auswählen

<?= $this->form->checkbox('foo', t('Language-string I want to extract'), 1, $values['foo'] == 1) ?>
Leider treten in einer Zeile aber auch mal 2 oder noch mehr Aufrufe dieser t-Funktion auf ... dann finde ich leider alles bis zum Ende des letzten Funktionsaufrufes .. .siehe hier:

Code: Alles auswählen

<?= $this->form->checkbox('foo', t('Language-string I want to extract'), 1, t('Second function-call in the same line')$values['foo'] == 1) ?>
findet dann natürlich das hier: Language-string I want to extract'), 1, t('Second function-call in the same line

Irgendwie müsste also REGEX so lauten:
Finde alles bis zum NÄCHSTEN vorkommen von ') ... und dann suche weitere Vorkommen.

Geht das und wenn JA .. wie ?

Re: Mal wieder REGEX

Verfasst: 02.05.2021 17:41
von Dr.Death
Aus dem Bauch heraus:

Den (.*) auf nicht gierig umstellen: (.*?)

Code: Alles auswählen

(?<=t\(')(.*?)(?='\))
findet dann aus: <?= $this->form->checkbox('foo', t('Language-string I want to extract'), 1, $values['foo'] == 1) ?>
folgendes:

<?= $this->form->checkbox('foo', t('Language-string I want to extract'), 1, t('Second function-call in the same line')$values['foo'] == 1) ?>

Den ersten kann man ja in $1 packen und der nächste wird in $2, §3 usw. sein.

Demo: https://regex101.com

Re: Mal wieder REGEX

Verfasst: 02.05.2021 18:07
von mad-manne
Hey Doc,
das ist vermutlich nur die halbe Lösung ...

Mit deiner REGEX findet er jetzt korrekterweise wieder Language-string I want to extract aber danach ist dann Schluss
Vermutlich muss dieser Ausdruck dann noch in eine "Schleife", um JEDES passende Pattern zu extrahieren... nur wie ??

Ich bin ja schon stolz wie Bolle, dass ich (übrigens auch auf regex101.com) die erste Lösung selbst gefunden hatte :grin:

LG,
Manne

EDIT: Ooops ... ich hatte zwischenzeitlich auf regex101 die Parameter g und m deaktiviert ... NUN geht's :D
Doc ... du bist der BESTE !

Re: Mal wieder REGEX

Verfasst: 03.05.2021 12:30
von mad-manne
Hmmm ... leider gibt es noch 2 Probleme (eins davon habe ich schon gelöst)

Ich hatte vergessen, dass es natürlich auch Aufrufe mit Parametern gibt so wie hier:

Code: Alles auswählen

        <?= t('New due-date: %s for the task "%s". Are you sure?', $task['confirm_pushed_date_due'], $task['title']) ?>
Also suche ich jetzt nicht mehr bis ') sondern nur noch bis '
REGEX dafür = (?<= t\(\')(.*?)(?=\')

ABER nun habe ich(hoffentlich) das letzte offene Problem, da es natürlich auch Strings mit einem ESCAPTEN Hochkomma gibt wie hier:

Code: Alles auswählen

    <h2><?= t('Push the task\'s due-date') ?></h2>
Und davon "bekomme" ich natürlich nur Push the task\ zurück anstatt Push the task\'s due-date :(

Ich müsste also REGEX sagen, dass es bis zum nächsten Vorkommen eines Hochkomma matchen soll, aber NUR, wenn dieses Hochkomma keinen Backslash davor hat.

Geht das auch noch ??
EDIT: Hier könnte man es testen https://regex101.com/r/IMnxZZ/1/

Freue mich über Feedback,
Manne

Re: Mal wieder REGEX

Verfasst: 03.05.2021 16:24
von Dr.Death
(?<= t\(\')(.*?[^\\])(?=\')


Im (.*?) hab ich ein: [^\\] hinzugefügt. --> (.*?[^\\])

Result:
<?= t('New due-date: %s for the task "%s". Are you sure?', $task['confirm_pushed_date_due'], $task['title']) ?>
<h2><?= t('Push the task\'s due-date') ?></h2>
Demo: https://regex101.com/r/QvTVs7/1

Re: Mal wieder REGEX

Verfasst: 03.05.2021 16:41
von mad-manne
Du bist mein HELD :geek:

Code: Alles auswählen

/**
 * Return an array of language-keys used in the given script
 *
 * @param string $script_file Script to search for calls to the translate-function t('foo')
 *
 * @return array
 */
function getScriptKeys($script_file) {
    $lang_keys = array();
    $lang_keys['script_file'] = $script_file;
    $all_lang_keys['lang_keys'] = array();
    // REGEXpression to find language-keys
    $regx_find_lang_keys = '/(?<= t\(\')(.*?[^\\\\])(?=\')/m';  // Thanks to DrDeath :-D ( https://github.com/DrDeath )

    $handle = @fopen($script_file, "r");

    ... / ...
EDIT: Ach sieh an ... du bist(natürlich) auch auf github ... gleich mal den DANK verlinkt :wink:

Mich findet man dort unter einem anderen Nickname