使用 PhP(歌曲名称)获取特定的正则表达式
Get a specific regex using PhP (Song names)
我一直在努力使用这个特定的正则表达式。
快速背景:
我下载了很多歌曲,给了它们正确的名字等等,但现在我希望它们在数据库中供我练习 AJAX、JSON、SQL 和 PhP.
每首歌都有相同的构建。
ARTIST - SONGNAME ft. ARTIST (ARTIST Remix)
所有斜体都是可选的。到目前为止,我设法获得了以下正则表达式来获取一些数据,但这还不够。
/(.*) - (.*) [ft\.]* (.*)/
然而,这需要 'ft.' 才能工作,并且该部分是可选的。
然后我决定做多个正则表达式,但我从来没有忘记艺术家姓名和歌曲名称,这仍然让我留下了 ft 和 () 部分。
我一直在使用 http://www.phpliveregex.com/ 实时练习一些歌曲。
以下是我要过滤的歌曲名称的一些示例:
Armin van Buuren - Rain ft. Cathy Burton (Urbanstep Remix).mp3
Alpha Drop - Spring Fever.mp3
Beatcore - Tonight ft. Lynn Boyer.mp3
iru1919 - 天狐.mp3
您可以通过在组后添加问号来使组可选:
(ft\.)?
在某些情况下,您可以使用花括号:
{ft\.}?
?
被称为 quantifier。
你必须使用像这样的正则表达式:
/(.*) - (.*)( (ft\.)? (.*))?(\([^)]+\))?/
您的正则表达式失败,因为 [ft\.]*
表示 'any of f,t or .',还因为 (.*) - (.*)
之后的 space 与第二个和第四个示例不匹配。
编辑:
最后,我认为这个正则表达式比我在上面发布的第一个要好:
/(.+) - ((?:(?!(ft\.|\()).)+)( *ft\.[^\(]+)?( *\(([^)]+)\))?\.([^.]+)$/
它分别匹配艺术家、标题、最终的 ft. 艺术家、最终的混音和文件扩展名。
请注意如果主打歌或主唱中有括号(有可能),则匹配失败。
我不是 regex 专家,所以我的解决方案很粗鲁,但我确信没有更好的解决方案。
定义:
下一个输入: 待进一步检查歌曲信息的字符串。
首先,我会将艺术家与歌曲名称的其余部分分开:
/(.*) - (.*)\.mp3$/
第一个反向引用是 'ARTIST'。第二个是下一个输入。
接下来我会搜索 'ARTIST Remix'(因为这是最容易搜索下一个):
/([^(]*)( \(([^)]*)\))?$/
第一个反向引用是下一个输入。第三个反向引用 ([^)]*)
引用 'ARTIST Remix'。第二个反向引用可以忽略,因为它不需要。它是 space 后跟方括号中的 'ARTIST Remix'。
现在您可以搜索精选 'ARTIST':
/(.*) ft\. (.*)/
如果有特色 'ARTIST',第一个反向引用是 'SONGNAME',第二个是特色 'ARTIST'。但是,如果没有特色 'ARTIST',那么您将得到一个空数组,因为没有匹配项。
当没有特征 'ARTIST',或者更具体地说,没有出现 ft.
时,下一个输入,即要检查的剩余字符串,是 'SONGNAME'。
正如其他人所说,[ft\.]*
将匹配任何列出的字符,以任何顺序,任意次数。
我建议这个正则表达式:
/^(.+?)\h+-\h+(.+?)(?:\h+(?:ft\.)?\h+(.*?))?\h*(?:\((.*?)\))?\.mp3$/
细分:
^
: 字符串开始
(.+?)
:一个或多个字符(非贪婪),捕获为第1组
\h+
:一个或多个横白-spaces(space,不间断space,...)
-
:文字连字符
\h+
:一个或多个横白-spaces(space,不间断space,...)
(.+?)
:一个或多个字符(非贪婪),捕获为第2组
(?: )?
:可选的,非捕获的,组,它有:
\h+
:一个或多个横白-spaces(space,不间断space,...)
(?:ft\.)?
:可选,非捕获文字 ft.
\h+
:一个或多个横白-spaces(space,不间断space,...)
(.*?)
:零个或多个字符(非贪婪),捕获为组 3
\h*
:零个或多个水平白色-spaces(space,不间断space,...)
(?: )?
:可选的,非捕获的,组,它有:
\(
: 文字 (
(.*?)
:零个或多个字符(非贪婪),捕获为组 4
\)
:文字 )
\.mp3
: 文字 .mp3
$
:字符串结尾,所以结合 ^
整个字符串必须匹配
用在PHP代码中,看起来像这样:
$songs = array(
'Armin van Buuren - Rain ft. Cathy Burton (Urbanstep Remix).mp3',
'Alpha Drop - Spring Fever.mp3',
'Beatcore - Tonight ft. Lynn Boyer.mp3',
'iru1919 - 天狐.mp3'
);
// Prepare results array
$results = array();
// Define key names that will be used in each element
$keys = array("artist", "songname", "featuring", "remixBy");
// Iterate over input
foreach($songs as $song) {
if (preg_match(
"/^(.+?)\h+-\h+(.+?)(?:\h+(?:ft\.)?\h+(.*?))?\h*(?:\((.*?)\))?\.mp3$/",
$song, $matches)) {
// Remove original string (at position 0)
array_shift($matches);
// Convert matched items (groups) to associative array
// and add to result
$results[] = array_combine($keys, array_pad($matches, 4, ''));
} else {
echo "This file name doesn't match the pattern: $song";
};
}
// Output results:
echo json_encode($results, JSON_PRETTY_PRINT);
输出为:
[
{
"artist": "Armin van Buuren",
"songname": "Rain",
"featuring": "Cathy Burton",
"remixBy": "Urbanstep Remix"
},
{
"artist": "Alpha Drop",
"songname": "Spring Fever",
"featuring": "",
"remixBy": ""
},
{
"artist": "Beatcore",
"songname": "Tonight",
"featuring": "Lynn Boyer",
"remixBy": ""
},
{
"artist": "iru1919",
"songname": "\u5929\u72d0",
"featuring": "",
"remixBy": ""
}
]
变体没有 "Remix"
如果您想从结果中排除单词 "Remix" 本身,那么您可以将正则表达式扩展为:
/^(.+?)\h+\-\h+(.+?)(?:\h+(?:ft\.)?\h+(.*?))?\h*(?:\((.*?)(?:\h+Remix)?\))?\.mp3$/
注意添加的组:
(?:\h+Remix)?
:一个非捕获的可选组,匹配一个或多个白色space和文字Remix
.
使用这种变体,第一首歌曲的输出将作为最后一个键:
"remixBy": "Urbanstep"
PHP
中的完整演练将是:
<?php
$string = 'Armin van Buuren - Rain ft. Cathy Burton (Urbanstep Remix).mp3
Alpha Drop - Spring Fever.mp3
Beatcore - Tonight ft. Lynn Boyer.mp3
iru1919 - 天狐.mp3';
$regex = '~ # delimiter
^ # anchors regex to the beginning
(?<artist>[^-]+) # capture everything but a dash to group "artist"
-
(?<rest>.*) # capture everything but .mp3 to group "rest"
(?:\.mp3)
$
~xm'; # multiline and freespace mode
preg_match_all($regex, $string, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$artist = trim($match["artist"]);
list($title, $artist2) = preg_split("~ft\.~", $match["rest"]);
echo "Artist: " . trim($artist) .
", Title: " . trim($title) .
(!empty($artist2)?", Second Artist: $artist2":"") .
"\n";
}
// output:
// Artist: Armin van Buuren, Title: Rain, Second Artist: Cathy Burton (Urbanstep Remix)
// Artist: Alpha Drop, Title: Spring Fever
// Artist: Beatcore, Title: Tonight, Second Artist: Lynn Boyer
// Artist: iru1919, Title: 天狐
?>
我一直在努力使用这个特定的正则表达式。
快速背景:
我下载了很多歌曲,给了它们正确的名字等等,但现在我希望它们在数据库中供我练习 AJAX、JSON、SQL 和 PhP.
每首歌都有相同的构建。
ARTIST - SONGNAME ft. ARTIST (ARTIST Remix)
所有斜体都是可选的。到目前为止,我设法获得了以下正则表达式来获取一些数据,但这还不够。
/(.*) - (.*) [ft\.]* (.*)/
然而,这需要 'ft.' 才能工作,并且该部分是可选的。 然后我决定做多个正则表达式,但我从来没有忘记艺术家姓名和歌曲名称,这仍然让我留下了 ft 和 () 部分。
我一直在使用 http://www.phpliveregex.com/ 实时练习一些歌曲。
以下是我要过滤的歌曲名称的一些示例:
Armin van Buuren - Rain ft. Cathy Burton (Urbanstep Remix).mp3
Alpha Drop - Spring Fever.mp3
Beatcore - Tonight ft. Lynn Boyer.mp3
iru1919 - 天狐.mp3
您可以通过在组后添加问号来使组可选:
(ft\.)?
在某些情况下,您可以使用花括号:
{ft\.}?
?
被称为 quantifier。
你必须使用像这样的正则表达式:
/(.*) - (.*)( (ft\.)? (.*))?(\([^)]+\))?/
您的正则表达式失败,因为 [ft\.]*
表示 'any of f,t or .',还因为 (.*) - (.*)
之后的 space 与第二个和第四个示例不匹配。
编辑:
最后,我认为这个正则表达式比我在上面发布的第一个要好:
/(.+) - ((?:(?!(ft\.|\()).)+)( *ft\.[^\(]+)?( *\(([^)]+)\))?\.([^.]+)$/
它分别匹配艺术家、标题、最终的 ft. 艺术家、最终的混音和文件扩展名。
请注意如果主打歌或主唱中有括号(有可能),则匹配失败。
我不是 regex 专家,所以我的解决方案很粗鲁,但我确信没有更好的解决方案。
定义:
下一个输入: 待进一步检查歌曲信息的字符串。
首先,我会将艺术家与歌曲名称的其余部分分开:
/(.*) - (.*)\.mp3$/
第一个反向引用是 'ARTIST'。第二个是下一个输入。
接下来我会搜索 'ARTIST Remix'(因为这是最容易搜索下一个):
/([^(]*)( \(([^)]*)\))?$/
第一个反向引用是下一个输入。第三个反向引用 ([^)]*)
引用 'ARTIST Remix'。第二个反向引用可以忽略,因为它不需要。它是 space 后跟方括号中的 'ARTIST Remix'。
现在您可以搜索精选 'ARTIST':
/(.*) ft\. (.*)/
如果有特色 'ARTIST',第一个反向引用是 'SONGNAME',第二个是特色 'ARTIST'。但是,如果没有特色 'ARTIST',那么您将得到一个空数组,因为没有匹配项。
当没有特征 'ARTIST',或者更具体地说,没有出现 ft.
时,下一个输入,即要检查的剩余字符串,是 'SONGNAME'。
正如其他人所说,[ft\.]*
将匹配任何列出的字符,以任何顺序,任意次数。
我建议这个正则表达式:
/^(.+?)\h+-\h+(.+?)(?:\h+(?:ft\.)?\h+(.*?))?\h*(?:\((.*?)\))?\.mp3$/
细分:
^
: 字符串开始(.+?)
:一个或多个字符(非贪婪),捕获为第1组\h+
:一个或多个横白-spaces(space,不间断space,...)-
:文字连字符\h+
:一个或多个横白-spaces(space,不间断space,...)(.+?)
:一个或多个字符(非贪婪),捕获为第2组(?: )?
:可选的,非捕获的,组,它有:\h+
:一个或多个横白-spaces(space,不间断space,...)(?:ft\.)?
:可选,非捕获文字ft.
\h+
:一个或多个横白-spaces(space,不间断space,...)(.*?)
:零个或多个字符(非贪婪),捕获为组 3
\h*
:零个或多个水平白色-spaces(space,不间断space,...)(?: )?
:可选的,非捕获的,组,它有:\(
: 文字(
(.*?)
:零个或多个字符(非贪婪),捕获为组 4\)
:文字)
\.mp3
: 文字.mp3
$
:字符串结尾,所以结合^
整个字符串必须匹配
用在PHP代码中,看起来像这样:
$songs = array(
'Armin van Buuren - Rain ft. Cathy Burton (Urbanstep Remix).mp3',
'Alpha Drop - Spring Fever.mp3',
'Beatcore - Tonight ft. Lynn Boyer.mp3',
'iru1919 - 天狐.mp3'
);
// Prepare results array
$results = array();
// Define key names that will be used in each element
$keys = array("artist", "songname", "featuring", "remixBy");
// Iterate over input
foreach($songs as $song) {
if (preg_match(
"/^(.+?)\h+-\h+(.+?)(?:\h+(?:ft\.)?\h+(.*?))?\h*(?:\((.*?)\))?\.mp3$/",
$song, $matches)) {
// Remove original string (at position 0)
array_shift($matches);
// Convert matched items (groups) to associative array
// and add to result
$results[] = array_combine($keys, array_pad($matches, 4, ''));
} else {
echo "This file name doesn't match the pattern: $song";
};
}
// Output results:
echo json_encode($results, JSON_PRETTY_PRINT);
输出为:
[
{
"artist": "Armin van Buuren",
"songname": "Rain",
"featuring": "Cathy Burton",
"remixBy": "Urbanstep Remix"
},
{
"artist": "Alpha Drop",
"songname": "Spring Fever",
"featuring": "",
"remixBy": ""
},
{
"artist": "Beatcore",
"songname": "Tonight",
"featuring": "Lynn Boyer",
"remixBy": ""
},
{
"artist": "iru1919",
"songname": "\u5929\u72d0",
"featuring": "",
"remixBy": ""
}
]
变体没有 "Remix"
如果您想从结果中排除单词 "Remix" 本身,那么您可以将正则表达式扩展为:
/^(.+?)\h+\-\h+(.+?)(?:\h+(?:ft\.)?\h+(.*?))?\h*(?:\((.*?)(?:\h+Remix)?\))?\.mp3$/
注意添加的组:
(?:\h+Remix)?
:一个非捕获的可选组,匹配一个或多个白色space和文字Remix
.
使用这种变体,第一首歌曲的输出将作为最后一个键:
"remixBy": "Urbanstep"
PHP
中的完整演练将是:
<?php
$string = 'Armin van Buuren - Rain ft. Cathy Burton (Urbanstep Remix).mp3
Alpha Drop - Spring Fever.mp3
Beatcore - Tonight ft. Lynn Boyer.mp3
iru1919 - 天狐.mp3';
$regex = '~ # delimiter
^ # anchors regex to the beginning
(?<artist>[^-]+) # capture everything but a dash to group "artist"
-
(?<rest>.*) # capture everything but .mp3 to group "rest"
(?:\.mp3)
$
~xm'; # multiline and freespace mode
preg_match_all($regex, $string, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$artist = trim($match["artist"]);
list($title, $artist2) = preg_split("~ft\.~", $match["rest"]);
echo "Artist: " . trim($artist) .
", Title: " . trim($title) .
(!empty($artist2)?", Second Artist: $artist2":"") .
"\n";
}
// output:
// Artist: Armin van Buuren, Title: Rain, Second Artist: Cathy Burton (Urbanstep Remix)
// Artist: Alpha Drop, Title: Spring Fever
// Artist: Beatcore, Title: Tonight, Second Artist: Lynn Boyer
// Artist: iru1919, Title: 天狐
?>