使用通配符匹配字符串

问题描述 投票:50回答:7

我想匹配字符串与通配符(*),其中通配符表示“任何”。例如:

*X = string must end with X
X* = string must start with X
*X* = string must contain X

此外,一些复合用途,如:

*X*YZ* = string contains X and contains YZ
X*YZ*P = string starts with X, contains YZ and ends with P.

有一个简单的算法来做到这一点?我不确定使用正则表达式(虽然这是一种可能性)。

为了澄清,用户将在上面输入一个过滤器框(尽可能简单的过滤器),我不希望他们自己编写正则表达式。所以我可以很容易地从上面的符号转换出来的东西会很好。

c# regex string wildcard
7个回答
21
投票

仅供参考,您可以使用VB.NET Like-Operator

string text = "x is not the same as X and yz not the same as YZ";
bool contains = LikeOperator.LikeString(text,"*X*YZ*", Microsoft.VisualBasic.CompareMethod.Binary);  

如果你想忽略这个案子,请使用CompareMethod.Text

你需要添加using Microsoft.VisualBasic.CompilerServices;


106
投票

通常,外卡使用两种类型的笑话:

  ? - any character  (one and only one)
  * - any characters (zero or more)

因此您可以轻松地将这些规则转换为适当的正则表达式

  // If you want to implement both "*" and "?"
  private static String WildCardToRegular(String value) {
    return "^" + Regex.Escape(value).Replace("\\?", ".").Replace("\\*", ".*") + "$"; 
  }

  // If you want to implement "*" only
  private static String WildCardToRegular(String value) {
    return "^" + Regex.Escape(value).Replace("\\*", ".*") + "$"; 
  }

然后你可以照常使用正则表达式:

  String test = "Some Data X";

  Boolean endsWithEx = Regex.IsMatch(test, WildCardToRegular("*X"));
  Boolean startsWithS = Regex.IsMatch(test, WildCardToRegular("S*"));
  Boolean containsD = Regex.IsMatch(test, WildCardToRegular("*D*"));

  // Starts with S, ends with X, contains "me" and "a" (in that order) 
  Boolean complex = Regex.IsMatch(test, WildCardToRegular("S*me*a*X"));

15
投票

使用来自WildcardPatternSystem.Management.Automation可能是一种选择。

pattern = new WildcardPattern(patternString);
pattern.IsMatch(stringToMatch);

Visual Studio UI可能不允许您将System.Management.Automation程序集添加到项目的引用中。如here所述,随意手动添加。


4
投票

*X*YZ* = string contains X and contains YZ

@".*X.*YZ"

X*YZ*P = string starts with X, contains YZ and ends with P.

@"^X.*YZ.*P$"

4
投票

通配符*可以翻译为.*.*?正则表达式模式。

您可能需要使用单行模式来匹配换行符号,在这种情况下,您可以使用(?s)作为正则表达式模式的一部分。

您可以为整个或部分模式设置它:

X* = > @"X(?s:.*)"
*X = > @"(?s:.*)X"
*X* = > @"(?s).*X.*"
*X*YZ* = > @"(?s).*X.*YZ.*"
X*YZ*P = > @"(?s:X.*YZ.*P)"

3
投票

当检查与Y *的匹配时,有必要考虑Regex IsMatch在XYZ中给出true。为了避免它,我使用“^”锚

isMatch(str1, "^" + str2.Replace("*", ".*?"));  

所以,完整的代码来解决你的问题

    bool isMatchStr(string str1, string str2)
    {
        string s1 = str1.Replace("*", ".*?");
        string s2 = str2.Replace("*", ".*?");
        bool r1 = Regex.IsMatch(s1, "^" + s2);
        bool r2 = Regex.IsMatch(s2, "^" + s1);
        return r1 || r2;
    }

-3
投票

C#控制台应用程序示例

命令行示例: C:/> App_Exe -Opy PythonFile.py 1 2 3 控制台输出: 参数列表:-Opy PythonFile.py 1 2 3 找到python文件名:PythonFile.py

using System;
using System.Text.RegularExpressions;           //Regex

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string cmdLine = String.Join(" ", args);

            bool bFileExtFlag = false;
            int argIndex = 0;
            Regex regex;
            foreach (string s in args)
            {
                //Search for the 1st occurrence of the "*.py" pattern
                regex = new Regex(@"(?s:.*)\056py", RegexOptions.IgnoreCase);
                bFileExtFlag = regex.IsMatch(s);
                if (bFileExtFlag == true)
                    break;
                argIndex++;
            };

            Console.WriteLine("Argument list: " + cmdLine);
            if (bFileExtFlag == true)
                Console.WriteLine("Found python filename: " + args[argIndex]);
            else
                Console.WriteLine("Python file with extension <.py> not found!");
        }


    }
}
© www.soinside.com 2019 - 2024. All rights reserved.