[英]How to get parts of a string using multiple patterns in PHP? [Answer: Use a regular expression, but how exactly?]
I know there are similar questions, (this one " How do you use a variable in a regular expression? " seems to be close), but I want to know (the best way) how to fix my problem.我知道有类似的问题,(这个“ 你如何在正则表达式中使用变量? ”似乎很接近),但我想知道(最好的方法)如何解决我的问题。
I have some patterns defined which I use to detect an artist and a title in some file names (of MP3 and other audio files).我定义了一些模式,用于检测某些文件名(MP3 和其他音频文件)中的艺术家和标题。 It is similar the way MP3tag (a well known Windows application) converts filenames into MP3 tags.它类似于 MP3tag(一个众所周知的 Windows 应用程序)将文件名转换为 MP3 标签的方式。 How to do this?这个怎么做?
Below a small test application.下面是一个小测试应用程序。 (Negative cases are missing, but you get the grip.) (没有负面案例,但你掌握了。)
<?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;
}
?>
I am quite sure I have to use a regular expression search (regex) for this.我很确定我必须为此使用正则表达式搜索(regex)。 I cannot think clearly right now (thanks to Corona).我现在无法清楚地思考(感谢 Corona)。 Help me out please.请帮帮我。 Very much appreciated!非常感谢!
I did something like this before for a script that helped me tag my music collection.我之前为帮助我标记我的音乐收藏的脚本做过类似的事情。 I used Named Capturing Groups .我使用了命名捕获组。
You just need to define the patterns that will match the different parts of the file inside the structure: (?P<name>pattern)
.您只需要定义将匹配结构内文件不同部分的模式: (?P<name>pattern)
。 Where name
is a tag that describes the pattern.其中name
是描述模式的标签。
Example:例子:
$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...
}
The solution is basically what David Gomez suggested.解决方案基本上是大卫戈麦斯建议的。 Works like a charm.奇迹般有效。 I can't imagine their are many other good solutions for this particular problem.我无法想象他们对于这个特定问题还有许多其他好的解决方案。 Here's my implementation (part of a class):这是我的实现(类的一部分):
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.