c# - truncar - Cadenas a juego con comodín
quitar caracteres de una cadena c# (7)
Me gustaría hacer coincidir las cadenas con un comodín (*), donde el comodín significa "cualquiera". Por ejemplo:
*X = string must end with X
X* = string must start with X
*X* = string must contain X
Además, algunos usos compuestos como:
*X*YZ* = string contains X and contains YZ
X*YZ*P = string starts with X, contains YZ and ends with P.
¿Hay un algoritmo simple para hacer esto? No estoy seguro sobre el uso de expresiones regulares (aunque es una posibilidad).
Para aclarar, los usuarios escribirán lo anterior en un cuadro de filtro (un filtro tan simple como sea posible), no quiero que tengan que escribir expresiones regulares ellos mismos. Entonces, algo que pueda transformar fácilmente de la notación anterior sería bueno.
A menudo, los comodines funcionan con dos tipos de comodines:
? - any character (one and only one)
* - any characters (zero or more)
para que pueda convertir fácilmente estas reglas en la expresión regular apropiada:
// 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("//*", ".*") + "$";
}
Y luego puedes usar Regex como de costumbre:
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"));
El uso de
WildcardPattern
de
System.Management.Automation
puede ser una opción.
pattern = new WildcardPattern(patternString);
pattern.IsMatch(stringToMatch);
Es posible que Visual Studio UI no le permita agregar el ensamblaje
System.Management.Automation
a las referencias de su proyecto.
Siéntase libre de agregarlo manualmente, como se describe
here
.
Es necesario tener en cuenta que Regex IsMatch da verdad con XYZ, al verificar la coincidencia con Y *. Para evitarlo, uso el ancla "^"
isMatch(str1, "^" + str2.Replace("*", ".*?"));
Entonces, el código completo para resolver su problema es
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;
}
Muestra de aplicación de consola C #
Muestra de línea de comando:
C: /> App_Exe -Opy PythonFile.py 1 2 3
Salida de consola:
Lista de argumentos: -Opy PythonFile.py 1 2 3
Nombre de archivo python encontrado: 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!");
}
}
}
Solo para su información, puede usar el 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);
Use
CompareMethod.Text
si desea ignorar el caso.
Debe agregar
using Microsoft.VisualBasic.CompilerServices;
.
Un comodín
*
se puede traducir como
.*
O.
.*?
patrón de expresiones regulares.
Es posible que necesite usar un modo de línea única para que coincida con los símbolos de línea nueva, y en este caso, puede usar
(?s)
como parte del patrón de expresiones regulares.
Puede configurarlo para todo o parte del patrón:
X* = > @"X(?s:.*)"
*X = > @"(?s:.*)X"
*X* = > @"(?s).*X.*"
*X*YZ* = > @"(?s).*X.*YZ.*"
X*YZ*P = > @"(?s:X.*YZ.*P)"
*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$"