如何将此字符串与正则表达式匹配?

时间:2009-08-09 07:04:44

标签: c# .net regex

基本上我有音乐文件名,例如:

<source> <target>

"Travis - Sing"   "Travis - Sing 2001.mp3"
"Travis - Sing"   "Travis - Sing Edit.mp3"
"Travis - Sing"   "Travis - Sing New Edit.mp3"
"Mission Impossible I"   "Mission Impossible I - Main Theme.mp3"
"Mission Impossible I"   "Mission Impossible II - Main Theme.mp3"
"Mesrine - Death Instinct"   "Mesrine - Death Instinct - Le Million.mp3"
"Mesrine - Public Enemy #1"   "Mesrine - Public Enemy #1 - Theme"
"Se7en"   "Se7en Motion Picture Soundtrack - Theme.mp3"

括号不包含在字符串中(仅用于演示)。

我试图将“来源”与“目标”值相匹配。

所以我已经有了源名称,但是现在我正在使用很多字符串解析来匹配这两个。如何使用Regex实现相同的目标?

编辑:似乎有一种混乱。

"Travis - Sing"是我的源字符串,我正在尝试将其匹配到:

"Travis - Sing (2001).mp3"
"Travis - Sing (Edit).mp3"
"Travis - Sing (New Edit).mp3"

EDIT2:删除了括号。

4 个答案:

答案 0 :(得分:3)

您似乎正在寻找以某个字符串开头的所有文件 - 这将回答您的所有示例。这可以很容易地实现,无需使用两个循环的正则表达式,或使用linq:

var matches = from source in sources
              select new
                      {
                          Source = source,
                          Targets = from file in targets
                                    where file.StartsWith(source)
                                    select file
                      };

您也可以使用正则表达式而不是StartsWith条件,例如:

where Regex.IsMatch(file, String.Format("^{0}", source), RegexOptions.IgnoreCase)

这可能会在很多方面进行优化,但安德鲁建议编写一个长模式,动态完成时不会更快。

答案 1 :(得分:2)

从您对我的评论的回答中我很确定您正在寻找这样简单的事情。

因此,您可以使用“|”分隔多个搜索字词。这是alternation construct.

class Program
{
    private static List<string> searchList = new List<string>
                                     {
                                         "Travis - Sing (2001).mp3",
                                         "Travis - Sing (Edit).mp3",
                                         "Mission Impossible I - Main Theme.mp3",
                                         "Mission Impossible II - Main Theme.mp3",
                                         "doesn't match"
                                     };

    static void Main(string[] args)
    {
        var matchRegex = new Regex("Travis - Sing|Mission Impossible I");
        var matchingStrings = searchList.Where(str => matchRegex.IsMatch(str));

        foreach (var str in matchingStrings)
        {
            Console.WriteLine(str);
        }
    }
}

修改的 如果您想知道自己匹配的内容,可以添加groups

    static void Main(string[] args)
    {
        var matchRegex = new Regex("(?<travis>Travis - Sing)|(?<mi>Mission Impossible I)");

        foreach (var str in searchList)
        {
            var match = matchRegex.Match(str);
            if (match.Success)
            {
                if (match.Groups["travis"].Success)
                {
                    Console.WriteLine(String.Format("{0} matches against travis", str));
                }
                else if (match.Groups["mi"].Success)
                {
                    Console.WriteLine(String.Format("{0} matches against mi", str));
                }
            }
        }
    }

答案 2 :(得分:1)

源和目标之间总是有多个空格吗?如果是这样,那么以下内容将匹配:

/^(.*?)\s{2,}(.*?)$/

它基本上匹配两个项目,一个在2 +空格的任何间隙之前,一个在该差距之后。 (捕获模式使用非贪婪的.*?,因此如果有超过2个空格,则额外的空格将不会被捕获。)

答案 3 :(得分:1)

以下方法更加健壮(允许在源和目标之间使用不同数量的空格或超量)。例如。目标可能在单词之间有额外的空格,但它仍然匹配。

首先确定字符串中允许作为单词分隔符的字符。然后使用分隔符将源和目标字符串拆分为标记。然后检查源中的单词是否作为开头词。

E.g。 (Java)我使用空格和连字符作为分隔符

public boolean isValidMatch(String source, String target){
    String[] sourceTokens = source.split("[\\s\\-]+");  // split on sequence of 
    //whitespaces or dashes. Two dashes between words will still split 
    //same as one dash.

    String[] targetTokens = target.split("[\\s\\-]+"); // split similarly
    if(sourceTokens.length>targetTokens.length){
        return false;
    }

    for(int i=0;i<souceTokens.length;i++){
        if(!sourceTokens[i].equals(targetTokens[i])){
            return false;
        }
    }
    return true;
}

PS:您可能想要添加点'。'如果您有源“Hello World”并且目标为“Hello World.mp3”,则将字符作为分隔符;目前它不会匹配,因为正则表达式不会在点上拆分但是如果你将分隔符集扩展为包括点,那么它将会。