在PHP中使用preg_match按多个分隔符拆分字符串

3

有一个字符串,最多由三部分组成:WriterDirectorProducer。我们称它们为“类别”。每个类别由两个部分组成,用冒号分隔:Label : Names,其中Label是上述类别名称之一,Names是由斜杠分隔的名称列表。例如:

Writer : Jeffrey Schenck / Peter Sullivan / Director : Brian Trenchard-Smith / jack / Producer : smith

我想使用preg_match函数将字符串按照类别名称和名称列表分成几个部分。 这里是我目前的代码:

$pattern = '/Writer : (?P<Writer>[\s\S]+?)Director : (?P<Director>[\s\S]+?)Producer : (?P<Producer>[\s\S]+)/';
$sentence = 'Writer : Jeffrey Schenck / Peter Sullivan / Director : Brian Trenchard-Smith / jack / Producer : smith';
preg_match($pattern, $sentence, $matches);

foreach($matches as $cat => $match) {
  // Do more
  // echo "<b>" . $cat . "</b>" . $match . "<br />";
}

如果字符串中恰好包含三个类别,则该脚本能正常工作。如果至少缺少一个类别,则该脚本将失败。


你需要测试是否有任何匹配。如果没有匹配,那么 $matches 是空的,你的 foreach 就不会执行任何操作。 - Marc B
1个回答

0
一种方法是使用众所周知的{{link1:}}量词创建可选组:
$pattern = '/^' .
  '(?:Writer *: *(?P<Writer>[^:]+))?' .
  '(?:Director *: *(?P<Director>[^:]+))?' .
  '(?:Producer *: *(?P<Producer>[^:]+))?' .
  '$/';
preg_match($pattern, $sentence, $matches);

(?:) 创建一个 非捕获组。注意,输出数组将由数字位置索引和名称索引进行索引,例如:

Array
(
    [0] => Writer : Jeffrey Schenck / Peter Sullivan / Director : Brian Trenchard-Smith / jack / Producer : smith
    [Writer] => Jeffrey Schenck / Peter Sullivan / 
    [1] => Jeffrey Schenck / Peter Sullivan / 
    [Director] => Brian Trenchard-Smith / jack / 
    [2] => Brian Trenchard-Smith / jack / 
    [Producer] => smith
    [3] => smith
)

另一种方法是使用带有额外处理的 preg_match_all
$pattern = '/(?<=:)[^:]+/';
if (preg_match_all($pattern, $sentence, $matches)) {
  $keys = ['Writer', 'Director', 'Producer'];
  for ($i = 0; $i < count($matches[0]); ++$i)
    // The isset() checks are skipped for clarity's sake
    $a[$keys[$i]] = $matches[0][$i];

  print_r($a);
}

(?<=:) 是一个正向 后顾断言,用于匹配 : 字符。在这种情况下,结果数组将呈现出整齐的外观:

Array
(
    [Writer] =>  Jeffrey Schenck / Peter Sullivan / Director 
    [Director] =>  Brian Trenchard-Smith / jack / Producer 
    [Producer] =>  smith
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接