Ich möchte Zeichenfolgen mit einem Platzhalter (*) abgleichen, wobei der Platzhalter "any" bedeutet. Zum Beispiel:
*X = string must end with X
X* = string must start with X
*X* = string must contain X
Einige zusammengesetzte Verwendungen wie:
*X*YZ* = string contains X and contains YZ
X*YZ*P = string starts with X, contains YZ and ends with P.
Gibt es dafür einen einfachen Algorithmus? Ich bin mir nicht sicher, ob ich Regex verwenden soll (obwohl dies möglich ist).
Zur Verdeutlichung geben die Benutzer das Obige in ein Filterfeld ein (so einfach wie möglich). Ich möchte nicht, dass sie selbst reguläre Ausdrücke schreiben müssen. Etwas, das ich leicht aus der obigen Notation transformieren kann, wäre also gut.
YZ ABC X
übereinstimmen*X*YZ*
, dh müssen die Teilzeichenfolgen sowohl in der Zeichenfolge als auch im Muster in derselben Reihenfolge angezeigt werden oder nicht? Ich würde annehmen, dass es nicht übereinstimmen sollte, aber "Zeichenfolge enthält X und enthält YZ" macht es nicht klar. Wenn es übereinstimmen sollte, sind alle aktuellen Antworten falsch.Antworten:
Nur zu Ihrer Information, Sie könnten den VB.NET Like-Operator verwenden :
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);
Verwenden
CompareMethod.Text
Sie diese Option, wenn Sie den Fall ignorieren möchten.Sie müssen hinzufügen
using Microsoft.VisualBasic.CompilerServices;
.quelle
Type or namespace name 'CompilerServices' does not exist in namespace 'Microsoft.VisualBasic' (are you missing an assembly reference?
Platzhalter funktionieren häufig mit zwei Arten von Jokern:
? - any character (one and only one) * - any characters (zero or more)
So können Sie diese Regeln leicht in geeignete reguläre Ausdrücke umwandeln :
// 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("\\*", ".*") + "$"; }
Und dann können Sie Regex wie gewohnt verwenden:
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"));
quelle
Directory.GetFiles
auch eine Erweiterung mit drei Buchstaben.htm
übereinstimmen würde.html
, eine Erweiterung.ai
mit zwei Buchstaben jedoch nicht mitaix
oder übereinstimmen würdeaifg
. Windows-Platzhalter sind auf den ersten Blick trivial, aber unter der Haube sind sie eine Reihe von älteren hyperkomplexen Regelsätzen.*
es sich um beliebige Zeichen (null oder mehr) und?
genau um ein Zeichen handelt.Die Verwendung von
WildcardPattern
vonSystem.Management.Automation
kann eine Option sein.pattern = new WildcardPattern(patternString); pattern.IsMatch(stringToMatch);
In der Visual Studio-Benutzeroberfläche können Sie möglicherweise keine
System.Management.Automation
Assembly zu Referenzen Ihres Projekts hinzufügen . Fühlen Sie sich frei, es manuell hinzuzufügen, wie hier beschrieben .quelle
Ein Platzhalter
*
kann übersetzt werden.*
oder.*?
RegexMuster.Möglicherweise müssen Sie einen Singleline-Modus verwenden, um Newline-Symbole abzugleichen. In diesem Fall können Sie ihn
(?s)
als Teil des Regex-Musters verwenden.Sie können es für das gesamte oder einen Teil des Musters festlegen:
X* = > @"X(?s:.*)" *X = > @"(?s:.*)X" *X* = > @"(?s).*X.*" *X*YZ* = > @"(?s).*X.*YZ.*" X*YZ*P = > @"(?s:X.*YZ.*P)"
quelle
*.htm
auch ein Windows-Platzhalter überein*.html
.*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$"
quelle
^
Start,$
EndeEs ist zu berücksichtigen, dass Regex IsMatch mit XYZ wahr ist, wenn die Übereinstimmung mit Y * überprüft wird. Um dies zu vermeiden, verwende ich den Anker "^"
isMatch(str1, "^" + str2.Replace("*", ".*?"));
Der vollständige Code zur Lösung Ihres Problems lautet also
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; }
quelle
Anwendungsbeispiel für die C # -Konsole
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!"); } } }
quelle