[英]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.