是的,这可以通过正则表达式实现。如果您自己编写掩码,则应立即将其编写为正则表达式。如果没有,您将不得不将其转换为一个,但这应该不会太难,一旦您看到模式的样子。
主要问题是,这些变量可以包含什么。为简单起见,对于它们中的每一个,我假设它们可以包含除反斜杠之外的任何字符。这样的字符由 匹配[^\\]
。这是一个否定字符类,它匹配除内部字符之外的所有字符(第一个反斜杠用于转义第二个反斜杠)。您可以重复此操作+
(至少需要一个字符)。对于赛道,我会例外,只允许数字。
所以这会让你的模式像
[^\\]+\\[^\\]+\\\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].Value
和中访问它们m.Groups["artist"].Captures[1].Value
。
如果你想断言它们是相同的——如果它们不同则只是不匹配——你可以使用反向引用来代替第二组。反向引用与它引用的组捕获的内容完全匹配:
(?<artist>[^\\]+)\\(?<album>[^\\]+)\\(?<track>\d+)[.]\s*\k<artist>\s*-\s*(?<title>[^\\]+)[.]mp3$
\k<artist>
确保您与artist
在路径中找到的完全匹配。
像皮特一样,我只能推荐这个教程。要进一步了解我在上面使用的构造,您可能需要特别查看这些小节:
学习正则表达式绝对值得你花时间。您不仅肯定会遇到另一个可以轻松解决的问题 - 当涉及到您选择的文本编辑器中的简单搜索和替换任务时,它还会大大提高您的工作效率。
编辑:最后一点。如果您要经常使用这种模式,并且性能很重要,那么您可能会从使用 .NET 的从右到左模式中获益良多。你可以像这样激活它
...
Dim r As Regex = new Regex(pattern, RegexOptions.RightToLeft)
...
但是,如果您想知道为什么会有所不同,我建议您阅读链接的教程。;)