Regex를 사용하여 문자열에서 와일드 카드 (* ,? 등) 검색을 수행해야합니다.
나는 (와일드 카드를 수행 할 필요가 *
, ?
등) 문자열을 검색하십시오. 이것이 내가 한 일입니다.
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");
}
위의 코드를 사용하면 "Found"블록이 타격을 입지 만 실제로는 안됩니다!
내 패턴이 "e *"이면 "Found"만 히트해야합니다.
내 이해 또는 요구 사항은 d * 검색이 "d"다음에 모든 문자가 포함 된 텍스트를 찾아야한다는 것입니다.
패턴을 "d. *"및 "e. *"로 변경해야합니까? .NET에서 Regex 클래스를 사용하는 동안 내부적으로 수행하는 와일드 카드에 대한 지원이 있습니까?
에서 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
글로브 표현의 올바른 정규 표현식 제제 d*
인 ^d
수단을 시작으로 그 무엇과 일치하는 d
.
string input = "Message";
string pattern = @"^d";
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
( @
이 경우 인용은 필요하지 않지만 많은 정규 표현식이 혼자 남겨 두어야하는 백 슬래시 이스케이프를 사용하고 독자에게이 문자열이 특별 함을 나타 내기 때문에 좋은 방법입니다).
Windows와 * nux는 와일드 카드를 다르게 취급합니다. *
, ?
및 .
Windows에서 매우 복잡한 방식으로 처리되어, 하나의 존재 또는 위치는 의미 다른 사람의를 변경합니다. * nux는 단순하게 유지하지만, 단지 하나의 단순한 패턴 일치 만 수행합니다. 그 외에도 Windows ?
는 0 또는 1 문자와 일치하고 Linux는 정확히 1 문자와 일치합니다.
이 문제에 대한 권위있는 문서를 찾지 못했습니다. 여기에 Windows 8 / XP (명령 줄, dir
특정 명령, Directory.GetFiles
방법도 동일한 규칙 사용) 및 Ubuntu Server 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
그것이 일치라고 a1
, PathMatchSpec
하지 말한다.
d*
0 개 이상의 " d
"문자 와 일치해야 함을 의미합니다 . 따라서 모든 문자열은 유효한 일치입니다. d+
대신 시도하십시오 !
와일드 카드 패턴을 지원하기 위해 와일드 카드를 RegEx 등가물로 대체합니다. 등이 *
될 .*
및 ?
됩니다 .?
. 그러면 위의 표현은d.*
와일드 카드 식을 정규식으로 변환해야합니다. 예를 들면 :
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));
}
You must escape special Regex symbols in input wildcard pattern (for example pattern *.txt
will equivalent to ^.*\.txt$
) So slashes, braces and many special symbols must be replaced with @"\" + s
, where s
- special Regex symbol.
I think @Dmitri has nice solution at Matching strings with wildcard https://stackoverflow.com/a/30300521/1726296
Based on his solution, I have created two extension methods. (credit goes to him)
May be helpful.
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));
}
Usage:
string pattern = "file.*";
var isMatched = "file.doc".WildCardMatch(pattern)
or
string xlsxFile = "file.xlsx"
var isMatched = xlsxFile.WildCardMatch(pattern)
All upper code is not correct to the end.
This is because when searching zz*foo* or zz* you will not get correct results.
And if you search "abcd*" in "abcd" in TotalCommander will he find a abcd file so all upper code is wrong.
Here is the correct code.
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;
}
You may want to use WildcardPattern
from System.Management.Automation
assembly. See my answer here.
'Nice programing' 카테고리의 다른 글
더 빠른 작업, re.match / search 또는 str.find는 무엇입니까? (0) | 2020.12.06 |
---|---|
SqlException catch 및 처리 (0) | 2020.12.06 |
android : configChanges =“orientation”은 조각에서 작동하지 않습니다. (0) | 2020.12.06 |
JavaScript style.display =“none”또는 jQuery .hide ()가 더 효율적입니까? (0) | 2020.12.06 |
인덱스가있는 @each 루프 (0) | 2020.12.06 |