簡體   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