preg_match/regex: Soll nur matchen, wenn bestimmtes Wort am Ende nicht vorkommt

Igäl

Erfahrenes Mitglied
Werte Gemeinde

Wiedermal stehe ich vor einem kleinen Problem, das aufgrund eines Kenntnismangels in einem bestimmten Bereich aufgetaucht ist. Das Thema ist Regex, wo ich über Basiskenntnisse verfüge und mich durchwursteln kann.

Ausgangslage: Ich habe ein Formular mit 64 Feldern. Diese will ich nicht alle manuell ansprechen und packe deshalb das ganze Formular in foreach. Regex soll mir dann die Felder formModalEditProps([a-zA-z]+) auslesen (bspw. gibt es einen Input namens 'formModalEditPropsAge', 'formModaleEditPropsWeight' etc.). Es gibt aber auch für fast alles eine Checkbox mit den passenden Namen 'formModalEditPropsAgeDisplay', 'formModaleEditPropsWeightDisplay', wo der User bestimmen kann, ob das in seinem Profil angezeigt wird oder nicht (CMS für meine D&D-Gruppe zur Charakterbewirtschaftung, nicht irgendein Tinderabklatsch :)).

PHP:
foreach($_POST as $k => $v)    {
    preg_match('/formModalEditProps([a-zA-z]+)/', $k, $field);
    preg_match('/formModalEditProps([a-zA-z]+Display)/', $k, $field_display);
}

Dieses Snippet erfasst schön alle meine Felder. Da eine nicht getickte Checkbox jedoch keinen Wert zurückgibt und entsprechend das Feld nicht im $_POST-Array erscheint, stellt mich das vor gewisse Probleme, da die erste preg_match-Funktion auch die Displayfelder erfasst, was ich nicht will...

Der folgende Codeschnippsel sorgt dafür, dass die Displayfelder nicht angezeigt werden. Allerdings fehlt dann bei jedem Feld der letzte Buchstabe, was wirklich extrem ungünstig ist, wie ihr euch vorstellen könnt.
PHP:
preg_match('/formModalEditProps([a-zA-z]+)[^Display]/', $k, $field);

Ich könnte zwar das hier schreiben:
PHP:
preg_match('/formModalEditProps([a-zA-z]+)([^Display])/', $k, $field);

Dann habe ich im Array $field einen Index [2] mit dem letzten Buchstaben. Ich könnte das dann in einer Schleife mit dem Index [1], also dem Rest des Feldnamens, concaten. Aber das widerstrebt mir, weil ich denke, dass es auch anders gehen muss und ich etwas übersehe.

Warum also schneidet mir das vorletzte Snippet den letzen Buchstaben des Formularfeldnamens ab? Und wo liegt der Weg zur sauberen Lösung?

Ich danke bestens für Inputs und verbleibe mit freundlichen Grüssen an die Community.

Dä Igäl
 
Mein Workaround. Ich denke RegEx, die zwischen den "normalen" und den "display" Feldern unterscheiden könnten, würden das Ganze eleganter gestalten. Aber vorderhand mal zufrieden, dass es läuft :)

PHP:
private function set_charprops()    {
    $param_arr = $param_set_fields = array();
    $no_checkbox_fields = array(
        "formModalEditPropsNickname", "formModalEditPropsGender", "formModalEditPropsAge",
        "formModalEditPropsHeight", "formModalEditPropsWeight",    "formModalEditPropsSubmit"
    );

    $param_arr[] = "chardata_props";

    foreach($_POST as $k => $v)    {
        if($k != "formModalDataAction")    {
            preg_match('/^formModalEditProps([a-zA-z]+)$/', $k, $field);

            if($field[0] == $k && !in_array($field[0], $no_checkbox_fields)) {
                $param_set_fields['Character'.$field[1]] = $v;
            }
            if(!array_key_exists($field[0].'Display', $_POST) && !in_array($field[0], $no_checkbox_fields)) {
                if(!preg_match('/^([a-zA-Z]+)(Display)$/', $field[0])) {
                    $param_set_fields['Character'.$field[1].'Display'] = 0;
                }
            }
        }
    }

    $param_arr[]= $param_set_fields;
    $param_arr[] = "WHERE UsrID = ?";
    $param_arr[] = array($_SESSION['user_id']);

    $this->db_con->db_interaction("update", $param_arr);
}
 
Ich nehme an, du willst damit sagen, dass ich die Felder "xy" und "xyDisplay" anhand der Menge der Submatches unterscheiden kann!?
 
Du kannst natürlich auch mit einem negative Lockbehind arbeiten. Das gibt nur Treffer ohne 'Display' aus.
Test auf regex101
Code:
^formModalEditProps(\w+)(?<!Display)$
 
Entschuldige bitte. Den Link habe ich übersehen. Danke auch für den impliziten Tip mit der Page regex101. So muss ich meinen Webserver nicht malträtieren. Die Sache funktioniert übrigends top. Herzlichen Dank!
 
Zurück