繁体   English   中英

如何在 PHP 中使用多个模式获取字符串的一部分? [答案:使用正则表达式,但究竟如何?]

[英]How to get parts of a string using multiple patterns in PHP? [Answer: Use a regular expression, but how exactly?]

我知道有类似的问题,(这个“ 你如何在正则表达式中使用变量? ”似乎很接近),但我想知道(最好的方法)如何解决我的问题。

我定义了一些模式,用于检测某些文件名(MP3 和其他音频文件)中的艺术家和标题。 它类似于 MP3tag(一个众所周知的 Windows 应用程序)将文件名转换为 MP3 标签的方式。 这个怎么做?

下面是一个小测试应用程序。 (没有负面案例,但你掌握了。)

<?php

define('SEARCHPATTERNS', array(
    '%track%. %artist% - %title%',
    '%track% - %artist% - %title%',
    '%track%. %title%',
    '%track% - %title%',
    '%title%'));

define('UNKNOWN_ARTIST_TITLE_ARRAY', array('?', '?'));

$fileNames = array(
    '0780. Janis Joplin - Mercedes Benz.mp3',
    '0780. Janis Joplin - Mercedes Benz.flac',

    '0780 - Janis Joplin - Mercedes Benz.mp3',
    '0780 - Janis Joplin - Mercedes Benz.flac',

    '0780. Mercedes Benz.mp3',
    '0780. Mercedes Benz.flac',

    '0780 - Mercedes Benz.mp3',
    '0780 - Mercedes Benz.flac',

    'Mercedes Benz.mp3',
    'Mercedes Benz.flac',
);

//Test some file names 
foreach($fileNames as $fileName)
{
    $titleAndArtist = GetTitleArtistUsingSearchPattern($fileName);
    var_dump($titleAndArtist);    
}

function GetTitleArtistUsingSearchPattern($fileName)
{
    foreach(SEARCHPATTERNS as $pattern)
    {
        $artist = '???????????'; //  Get it from fileName if it matches the pattern, but how?
        $title = '???????????'; //  Get it from fileName if it matches the pattern, but how?

        if(true) // If is matches.... How?
        {
            return array(
                empty($artist) ? UNKNOWN_ARTIST_TITLE_STRINGS[0] : $artist,
                empty($title) ? UNKNOWN_ARTIST_TITLE_STRINGS[1] : $title
            );
        } 
    }

    return UNKNOWN_ARTIST_TITLE_ARRAY;    

}

?>

我很确定我必须为此使用正则表达式搜索(regex)。 我现在无法清楚地思考(感谢 Corona)。 请帮帮我。 非常感谢!

我之前为帮助我标记我的音乐收藏的脚本做过类似的事情。 我使用了命名捕获组

您只需要定义将匹配结构内文件不同部分的模式: (?P<name>pattern) 其中name是描述模式的标签。

例子:

$patterns = [
  //This will match `00. artist - title.ext`
  '/(?P<track>[0-9]{2})\.\s(?P<artist>.+)\s-\s(?P<title>.+)\.([a-z0-9]{3,4})/i',
  //This will match `00. title.ext`
  '/(?P<track>[0-9]{2})\.\s(?P<title>.+)\.([a-z0-9]{3,4})/i',
  //This will match `artist - album - 00 title.ext`
  '/(?P<artist>.+)\s-\s(?P<album>.+)\s-\s(?P<track>[0-9]{2})\s(?P<title>.+)\.[a-z0-9]{3,4}/i'

  // and so on...
];

$filename = "01. Cool Band - Song Title.flac";
$matches = [];
foreach($patterns as $pattern) {
  preg_match($pattern, $filename, $matches);

  //Matched artist?
  $artist = $matches['artist'] ?? false;

  //Matched song title?
  $title = $matches['title'] ?? false;

  //Matched album?
  $album = $matches['album'] ?? false;

  //etc...
}

解决方案基本上是大卫戈麦斯建议的。 奇迹般有效。 我无法想象他们对于这个特定问题还有许多其他好的解决方案。 这是我的实现(类的一部分):

private function GetTrackInfoFromFileName($fileName, &$item,  $defaultValue = '?')
{
    $patterns = array(          
        '/(?P<track>\d{1,4})\.\s(?P<artist>.+)\s-\s(?P<title>.+)\.([a-z0-9]{3,4})/i', //Matches `0000. artist - title.ext`
        '/(?P<track>\d{1,4})\s-\s(?P<artist>.+)\s-\s(?P<title>.+)\.([a-z0-9]{3,4})/i', //Matches `0000 - artist - title.ext`
        '/(?P<artist>.+)\s-\s(?P<title>.+)\.([a-z0-9]{3,4})/i', //Matches `artist - title.ext`
        '/(?P<track>\d{1,4})\.\s(?P<title>.+)\.([a-z0-9]{3,4})/i', //Matches `0000. title.ext`
    ); 

    $matches = [];

    foreach($patterns as $pattern)
    {
        preg_match($pattern, $fileName, $matches);
        if(empty($matches))
        {
            continue;
        }
        $item['artist'] = $matches['artist'] ?? $defaultValue;
        $item['title'] = $matches['title']  ?? $defaultValue;
        $item['track'] = isset($matches['track']) ? array($matches['track']) : array($defaultValue);
        return;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM