在VB.Net中使用RegEx从文件名中获取歌曲信息

时间:2013-06-12 23:43:59

标签: regex vb.net

所以我需要一个正则表达式的忍者来帮助我,因为我对Regex知之甚少。我希望能够根据掩码从文件名中检索有关歌曲的信息。这是一个例子:

G:\Music\G\Green Day\(2001) International Superhits!\02. Green Day - Poprocks & Coke.mp3

所以面具将是:

$artist$\$album$\$track$. $artist$ - $title$.mp3

似乎Regex对此非常完美,因为它只是处理字符串。有人有解决方案吗?

谢谢, 好色

P.S。我知道如何通过代码来实现...希望用Regex完成它。

2 个答案:

答案 0 :(得分:3)

是的,正则表达式可以实现这一点。如果您自己编写掩码,则应该立即将其写为正则表达式。如果没有,你将不得不把它变成一个,但是一旦看到模式的样子,那就不会太难了。

主要问题是,这些变量可能包含什么。为简单起见,对于它们中的每一个,我将假设它们可以包含除反斜杠之外的任何字符。这样的字符由[^\\]匹配。这是一个否定的字符类,它匹配除了包含在内的字符之外的所有内容(并且第一个反斜杠是为了逃避第二个反斜杠)。您可以使用+重复此操作(至少需要一个字符)。对于曲目我会做一个例外,只允许数字。

这样会使你的模式像

[^\\]+\\[^\\]+\\\d+[.]\s*[^\\]+\s*-\s*[^\\]+[.]mp3$

$是将模式锚定到字符串的末尾。

请注意,我将句点放在字符类中。否则他们会匹配除换行符之外的任何字符 - 你也可以逃避句点,但我更喜欢字符类的可读性。对于空格,我使用\s*,它匹配任意数量(和种类)的空格,包括根本没有空格。

现在的问题是如何将这个变成你的变量。您可以通过在括号中包围所需部分来捕获部分匹配。但更有用的是,您可以使用(?<name>pattern)语法提供这些捕获名称。像这样:

(?<artist>[^\\]+)\\(?<album>[^\\]+)\\(?<track>\d+)[.]\s*(?<artist>[^\\]+)\s*-\s*(?<title>[^\\]+)[.]mp3$

最后,您如何访问结果?

Dim text As String = "G:\Music\G\Green Day\(2001) International Superhits!\02. Green Day - Poprocks & Coke.mp3" 
Dim pattern As String = "(?<artist>[^\\]+)\\(?<album>[^\\]+)\\(?<track>\d+)[.]\s*(?<artist>[^\\]+)\s*-\s*(?<title>[^\\]+)[.]mp3$" 

' Instantiate the regular expression object. 
Dim r As Regex = new Regex(pattern)

' Match the regular expression pattern against a text string. 
Dim m As Match = r.Match(text)
If m.Success Then
    ' get results from m.Groups["artist"].Value etc.

还有一个微妙之处。你的面具/图案包含艺术家两次。 .NET对重复的组名没有问题。问题是你想如何处理两个不同名称的情况。我上面写的代码只会给你两个版本中的后一个。实际上,您可以在m.Groups["artist"].Captures[0].Valuem.Groups["artist"].Captures[1].Value中访问它们。

如果你想声明它们两者是相同的 - 如果它们不相同则只是不匹配 - 你可以使用反向引用来代替第二组。反向引用完全匹配它引用的组所捕获的内容:

(?<artist>[^\\]+)\\(?<album>[^\\]+)\\(?<track>\d+)[.]\s*\k<artist>\s*-\s*(?<title>[^\\]+)[.]mp3$

\k<artist>确保您完全匹配在路径中找到的artist

像皮特一样,我只能推荐this tutorial。为了进一步了解我上面使用的构造,您可能希望特别查看这些小节:

学习正则表达式绝对值得您花时间。您不仅会遇到另一个可以轻松解决的问题 - 在您选择的文本编辑器中进行简单的搜索和替换任务时,它还可以提高您的工作效率。

编辑:最后一点说明。如果您要使用这种模式,并且性能至关重要,那么使用.NET的从右到左模式可能会获得很多收益。您可以像

一样激活它
...
Dim r As Regex = new Regex(pattern, RegexOptions.RightToLeft)
...

但是如果你想知道为什么会产生影响,我建议你阅读链接教程。 ;)

答案 1 :(得分:0)

我相信这对你有用:

^(?<drive>[^:]+):\\(?<folder>Music)\\(?<subfolder>[^\\]+)\\(?<group>[^(]+)\\\((?<year>[^)]+)\)\s+(?<album>[^\\]+)\\(?<track>[^.]+)\.\s*(?<artist>.+?) - (?<title>[^.]+)\.mp3$

将其分解以获得解释:

^                       'start of string
(?<drive>[^:]+)         'named capture group "drive", captures any character except :
:\\                     'finds : followed by "\" ("\" has to be escaped to be a literal "\", so \\ is needed here)
(?<folder>Music)        'named capture group "folder", captures Music
\\                      'finds "\"
(?<subfolder>[^\\]+)    'named capture group "subfolder", captures any character except "\"
\\                      'finds "\"
(?<group>[^(]+)         'named capture group "group", captures any character except "\"
\\                      'finds "\"
\(                      'finds ( (parentheses must be escaped to be a literal "(" or literal ")", so \( is needed here)
(?<year>[^)]+)\)        'named capture group "year", captures any character except "("
\s+                     'finds whitespace
(?<album>[^\\]+)        'named capture group "album", captures any character except "("
\\                      'finds "\"
(?<track>[^.]+)         'named capture group "track", captures any character except "."
\.                      'finds "." (outside of a character class, "." must be escaped, so \. is needed here)
\s*                     'finds whitespace
(?<artist>.+?)          'named capture group "artist", captures any character (lazily)
 -                      'finds " - "
(?<title>[^.]+)         'named capture group "title", captures any character (greedily)
\.mp3                   'finds ".mp3"
$                       'end of string

这是一个非常好的正则表达式在线入门:http://www.regular-expressions.info/

我可能会补充一点,对于离线资源,你肯定比O'Reilly Media的Jeffrey E.F.Friedl的“掌握正则表达式”更糟糕。我有第2版,它帮助我理解正则表达式,我很少需要提出有关正则表达式的问题。

我还购买了(并且喜欢)Jan Goyvaerts的RegexBuddy。这是用于撰写和理解Regex的非凡软件。