Regex / PHP n00b hier. Ich versuche die PHP "preg_split" Funktion zu benutzen ...

Ich habe Zeichenfolgen, die einem ganz bestimmten Muster folgen, nach dem ich sie aufteilen möchte.

Beispiel einer Zeichenfolge:

CADAVRES [FILM] (Kanada: Québec, Érik Canuel, 2009, lange Métrage) FICTION

Erwünschtes Ergebnis:

[0]CADAVRES
[1]FILM
[2]Canada : Québec
[3]Érik Canuel
[4]2009
[5]long métrage
[6]FICTION

Trennzeichen (in der Reihenfolge ihres Auftretens):

" ["
"] ("
", "
", "
", "
") "

Wie schreibe ich den regulären Ausdruck richtig?

Folgendes habe ich versucht:

<?php
$pattern = "/\s\[/\]\s\(/,\s/,\s/,\s/\)\s/";
$string = "CADAVRES [FILM] (Canada : Québec, Érik Canuel, 2009, long métrage) FICTION";
$keywords = preg_split($pattern, $string);
print_r($keywords);

Es funktioniert nicht und ich verstehe nicht, was ich falsch mache. Andererseits habe ich gerade angefangen, mit Regex und PHP umzugehen, also ja ... Es gibt so viele Fluchtzeichen, dass ich nicht richtig sehen kann ...

Vielen Dank!

2
Etienne Lehoux-Jobin 18 Jän. 2019 im 06:30

3 Antworten

Beste Antwort

Hier ist ein Versuch mit preg_match:

$pattern = "/^([^\[]+)\[([^\]]+)\]\s+\(([^,]+),\s+([^,]+),\s+([^,]+),\s+([^,]+)\)\s+(.+)$/i";
$string = "CADAVRES [FILM] (Canada : Québec, Érik Canuel, 2009, long métrage) FICTION";
preg_match($pattern, $string, $keywords);
array_shift($keywords);
print_r($keywords);

Ausgabe:

Array
(
    [0] => CADAVRES 
    [1] => FILM
    [2] => Canada : Québec
    [3] => Érik Canuel
    [4] => 2009
    [5] => long métrage
    [6] => FICTION
)

Versuch es!

Regex-Aufschlüsselung:

^   anchor to start of string
 (    begin capture group 1
  [^\[]+   one or more non-left bracket characters
        )   end capture group 1
         \[   literal left bracket
           (   begin capture group 2
            [^\]]+   one or more non-right bracket characters
                  )    end capture group 2
                   \]   literal bracket
                     \s+    one or more spaces
                        \(    literal open parenthesis
                          (     open capture group 3
                           [^,]+   one or more non-comma characters
                                )     end capture group 3
                                 ,\s+     literal comma followed by one or more spaces
                                     ([^,]+),\s+([^,]+),\s+([^,]+)   repeats of the above
                                                                  \)   literal closing parenthesis
                                                                    \s+   one or more spaces
                                                                       (  begin capture group 7
                                                                        .+  everything else
                                                                           )  end capture group 7
                                                                            $ EOL

Dies setzt voraus, dass Ihre Struktur statisch ist und nicht besonders hübsch ist, sollte aber andererseits robust gegenüber Trennzeichen sein, die sich in Felder einschleichen, in denen sie nicht sein sollen. Zum Beispiel erscheint der Titel mit einem : oder , plausibel und würde eine Lösung vom Typ "Aufteilung dieser Trennzeichen überall" aufheben. Beispielsweise,

"Matrix:, Trilogy()   [FILM, reviewed: good]    (Canada() :   Québec  ,  \t Érik Canuel , ): 2009 ,   long ():():[][]métrage) FICTIO  , [(:N";

Richtig analysiert als:

Array
(
    [0] => Matrix:, Trilogy()   
    [1] => FILM, reviewed: good
    [2] => Canada() :   Québec  
    [3] => Érik Canuel 
    [4] => ): 2009 
    [5] => long ():():[][]métrage
    [6] => FICTIO  , [(:N
)

Versuch es!

Wenn Ihr Kommabereich in Klammern eine variable Länge hat, möchten Sie diesen möglicherweise zuerst extrahieren und analysieren und dann den Rest der Zeichenfolge verarbeiten.

1
ggorlen 18 Jän. 2019 im 04:44

Ich habe es geschafft, mit preg_match_all eine Lösung zu finden:

$input = "CADAVRES [FILM] (Canada : Québec, Érik Canuel, 2009, long métrage) FICTION";
preg_match_all("|[^-\\[\\](),/\\s]+(?:(?: :)? [^-\\[\\](),/]+)?|", $input, $matches);
print_r($matches[0]);

Array
(
    [0] => CADAVRES
    [1] => FILM
    [2] => Canada : Québec
    [3] => Érik Canuel
    [4] => 2009
    [5] => long métrage
    [6] => FICTION
)

Der obige reguläre Ausdruck betrachtet einen Begriff als ein beliebiges Zeichen, bei dem es sich nicht um Klammern, Kommas, Klammern usw. handelt. Er erlaubt auch Begriffe mit zwei Wörtern, möglicherweise mit einem Doppelpunkttrennzeichen in der Mitte.

3
Tim Biegeleisen 18 Jän. 2019 im 03:39

Sie können diesen regulären Ausdruck verwenden, um Folgendes aufzuteilen:

([^\w:]\s[^\w:]?|\s[^\w:])

Es wird nach einem Nicht- (Wort oder :) Zeichen gesucht, gefolgt von einem Leerzeichen, gefolgt von einem optionalen Nicht- (Wort oder :) Zeichen. oder ein Leerzeichen, gefolgt von einem Nicht- (Wort oder :) Zeichen. Dies entspricht allen gewünschten Teilungsmustern. In PHP (beachten Sie, dass Sie den Modifikator u benötigen, um mit Unicode-Zeichen umgehen zu können):

$input = "CADAVRES [FILM] (Canada : Québec, Érik Canuel, 2009, long métrage) FICTION";
$keywords = preg_split('/([^\w:]\s[^\w:]?|\s[^\w:])/u', $input);
print_r($keywords);

Ausgabe:

Array
(
    [0] => CADAVRES 
    [1] => FILM
    [2] => Canada : Québec
    [3] => Érik Canuel
    [4] => 2009
    [5] => long métrage
    [6] => FICTION
)

Demo auf 3v4l.org

3
Nick 18 Jän. 2019 im 04:08