需要使用Regex对string执行通配符(*,?等)search

我需要对string执行通配符( * ,?等)search。 这是我所做的:

 string input = "Message"; string pattern = "d*"; Regex regex = new Regex(pattern, RegexOptions.IgnoreCase); if (regex.IsMatch(input)) { MessageBox.Show("Found"); } else { MessageBox.Show("Not Found"); } 

与上面的代码“find”块是打,但实际上不应该!

如果我的模式是“e *”,那么只有“find”应该打。

我的理解或要求是d *search应该find包含“d”的文本后跟任何字符。

我应该改变我的模式为“d。*”和“e。*”吗? 在使用正则expression式类的内部是否有任何支持.NET的通配符?

这并不难。 来自http://www.codeproject.com/KB/recipes/wildcardtoregex.aspx

 public static string WildcardToRegex(string pattern) { return "^" + Regex.Escape(pattern) .Replace(@"\*", ".*") .Replace(@"\?", ".") + "$"; } 

那么像foo*.xls? 将变成^foo.*\.xls.$

您可以使用名为LikeString的Visual Basic函数来执行没有RegEx的简单通配符。

 using Microsoft.VisualBasic; using Microsoft.VisualBasic.CompilerServices; if (Operators.LikeString("This is just a test", "*just*", CompareMethod.Text)) { Console.WriteLine("This matched!"); } 

如果您使用CompareMethod.Text ,它将比较不区分大小写。 对于区分大小写的比较,可以使用CompareMethod.Binary

更多信息: http : //www.henrikbrinch.dk/Blog/2012/02/14/Wildcard-matching-in-C

MSDN: http : //msdn.microsoft.com/en-us/library/microsoft.visualbasic.compilerservices.operators.likestring%28v=vs.100%29.ASPX

globexpression式d*的正确的正则expression式是^d ,这意味着匹配任何以d开头的东西。

  string input = "Message"; string pattern = @"^d"; Regex regex = new Regex(pattern, RegexOptions.IgnoreCase); 

(在这种情况下@引用是不必要的,但是很好的做法,因为许多正则expression式使用了需要单独保留的反斜杠转义,并且它也向读者指出这个string是特殊的)。

Windows和* nux以不同的方式处理通配符。 * ?. 由Windows以非常复杂的方式处理,一个人的存在或位置会改变另一个人的意思。 虽然* nux保持简单,但它只是一个简单的模式匹配。 除此之外,Windows匹配? 对于0或1个字符,Linux匹配恰好为1个字符。

我没有find有关这个问题的权威性文件,这里只是基于Windows 8 / XP(命令行, dir命令具体,而Directory.GetFiles方法也使用相同的规则)的testing日的结论和Ubuntu服务器12.04.1( ls命令)。 我做了几十个常见和不常见的案例,虽然也有很多失败的案例。

Gabe目前的答案,就像* nux。 如果你也想要一个Windows风格的,并且愿意接受这个不完美的话,那么这里是:

  /// <summary> /// <para>Tests if a file name matches the given wildcard pattern, uses the same rule as shell commands.</para> /// </summary> /// <param name="fileName">The file name to test, without folder.</param> /// <param name="pattern">A wildcard pattern which can use char * to match any amount of characters; or char ? to match one character.</param> /// <param name="unixStyle">If true, use the *nix style wildcard rules; otherwise use windows style rules.</param> /// <returns>true if the file name matches the pattern, false otherwise.</returns> public static bool MatchesWildcard(this string fileName, string pattern, bool unixStyle) { if (fileName == null) throw new ArgumentNullException("fileName"); if (pattern == null) throw new ArgumentNullException("pattern"); if (unixStyle) return WildcardMatchesUnixStyle(pattern, fileName); return WildcardMatchesWindowsStyle(fileName, pattern); } private static bool WildcardMatchesWindowsStyle(string fileName, string pattern) { var dotdot = pattern.IndexOf("..", StringComparison.Ordinal); if (dotdot >= 0) { for (var i = dotdot; i < pattern.Length; i++) if (pattern[i] != '.') return false; } var normalized = Regex.Replace(pattern, @"\.+$", ""); var endsWithDot = normalized.Length != pattern.Length; var endWeight = 0; if (endsWithDot) { var lastNonWildcard = normalized.Length - 1; for (; lastNonWildcard >= 0; lastNonWildcard--) { var c = normalized[lastNonWildcard]; if (c == '*') endWeight += short.MaxValue; else if (c == '?') endWeight += 1; else break; } if (endWeight > 0) normalized = normalized.Substring(0, lastNonWildcard + 1); } var endsWithWildcardDot = endWeight > 0; var endsWithDotWildcardDot = endsWithWildcardDot && normalized.EndsWith("."); if (endsWithDotWildcardDot) normalized = normalized.Substring(0, normalized.Length - 1); normalized = Regex.Replace(normalized, @"(?!^)(\.\*)+$", @".*"); var escaped = Regex.Escape(normalized); string head, tail; if (endsWithDotWildcardDot) { head = "^" + escaped; tail = @"(\.[^.]{0," + endWeight + "})?$"; } else if (endsWithWildcardDot) { head = "^" + escaped; tail = "[^.]{0," + endWeight + "}$"; } else { head = "^" + escaped; tail = "$"; } if (head.EndsWith(@"\.\*") && head.Length > 5) { head = head.Substring(0, head.Length - 4); tail = @"(\..*)?" + tail; } var regex = head.Replace(@"\*", ".*").Replace(@"\?", "[^.]?") + tail; return Regex.IsMatch(fileName, regex, RegexOptions.IgnoreCase); } private static bool WildcardMatchesUnixStyle(string pattern, string text) { var regex = "^" + Regex.Escape(pattern) .Replace("\\*", ".*") .Replace("\\?", ".") + "$"; return Regex.IsMatch(text, regex); } 

有一个有趣的事情,即使Windows API PathMatchSpec不同意FindFirstFile 。 试试看a1*.FindFirstFile表示它匹配a1PathMatchSpec说不。

d*表示它应该匹配零个或多个“ d ”个字符。 所以任何string都是有效的匹配。 试试d+吧!

为了支持通配符模式,我会用RegEx替代通配符。 像*变成.*? 变成了.? 。 那么你的expression式就变成了d.*

您需要将通配符expression式转换为正则expression式。 例如:

  private bool WildcardMatch(String s, String wildcard, bool case_sensitive) { // Replace the * with an .* and the ? with a dot. Put ^ at the // beginning and a $ at the end String pattern = "^" + Regex.Escape(wildcard).Replace(@"\*", ".*").Replace(@"\?", ".") + "$"; // Now, run the Regex as you already know Regex regex; if(case_sensitive) regex = new Regex(pattern); else regex = new Regex(pattern, RegexOptions.IgnoreCase); return(regex.IsMatch(s)); } 

您必须在input通配符模式中转义特殊的正则expression式符号(例如pattern *.txt将相当于^.*\.txt$ )因此,必须用@"\" + sreplace大括号和许多特殊符号,其中s -特殊的正​​则expression式符号。

所有上面的代码是不正确的。

这是因为当searchzz * foo *或zz *时,您将无法得到正确的结果。

如果您在TotalCommander的“abcd”中search“abcd *”,他会find一个abcd文件,所以上面的代码都是错误的。

这是正确的代码。

 public string WildcardToRegex(string pattern) { string result= Regex.Escape(pattern). Replace(@"\*", ".+?"). Replace(@"\?", "."); if (result.EndsWith(".+?")) { result = result.Remove(result.Length - 3, 3); result += ".*"; } return result; } 

您可能需要从System.Management.Automation程序System.Management.Automation使用WildcardPattern 。 在这里看到我的答案。

我认为@Dmitri在通配符匹配string有很好的解决schemehttps://stackoverflow.com/a/30300521/1726296

基于他的解决scheme,我创build了两种扩展方法。 (信贷给他)

可能有帮助。

 public static String WildCardToRegular(this String value) { return "^" + Regex.Escape(value).Replace("\\?", ".").Replace("\\*", ".*") + "$"; } public static bool WildCardMatch(this String value,string pattern,bool ignoreCase = true) { if (ignoreCase) return Regex.IsMatch(value, WildCardToRegular(pattern), RegexOptions.IgnoreCase); return Regex.IsMatch(value, WildCardToRegular(pattern)); } 

用法:

 string pattern = "file.*"; var isMatched = "file.doc".WildCardMatch(pattern) 

要么

 string xlsxFile = "file.xlsx" var isMatched = xlsxFile.WildCardMatch(pattern)