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