preg_split:根据非常特定的模式分割字符串

时间:2019-01-18 03:30:29

标签: php regex preg-split

此处为Regex / PHP n00b。我正在尝试使用PHP的“ preg_split”功能...

我有一些遵循非常特定模式的字符串,我希望根据这些模式进行拆分。

字符串示例:

  

CADAVRES [FILM](加拿大:魁北克,埃里克·坎努埃尔,2009年,长期居住)假想

所需结果:

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

定界符(按出现的顺序):

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

如何正确编写正则表达式?

这是我尝试过的:

<?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);

它不起作用,我不明白自己在做什么错。再说一次,我刚刚开始尝试处理正则表达式和PHP,所以是的。。。转义字符太多了,我看不到。。。

非常感谢您!

3 个答案:

答案 0 :(得分:3)

我设法使用<pages controlRenderingCompatibilityVersion="4.5"/> 制定了解决方案:

preg_match_all

以上正则表达式将术语视为任何字符,这些字符与方括号,逗号,括号等不一样。它还允许使用两个单词,可能在中间带有冒号。

答案 1 :(得分:3)

您可以使用此正则表达式拆分:

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

它寻找一个非(word或:)字符,后跟一个空格,然后是一个可选的非(word或:)字符;或空格后跟非(单词或:)字符。这将与您所需的所有拆分模式匹配。在PHP中(请注意,您需要使用u修饰符来处理unicode字符):

$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);

输出:

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

Demo on 3v4l.org

答案 2 :(得分:1)

尝试使用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);

输出:

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

Try it!

正则表达式细目:

^   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

这假定您的结构是静态的,并且不是特别漂亮,但另一方面,它对于分隔符不应该进入的字段应该是健壮的。例如,标题中带有:,的标题似乎是合理的,并且会破坏“在这些分隔符处随处拆分”类型的解决方案。例如,

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

正确解析为:

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

Try it!

此外,如果带括号的逗号区域的长度可变,则可能要先提取该区域并进行解析,然后再处理其余的字符串。