Je dois utiliser une expression régulière pour conserver les 4 derniers caractères d'une chaîne. Je ne connais pas la longueur de la chaîne, je dois donc commencer par la fin et compter à rebours. Le programme est écrit en c #.
Voici deux exemples de chaînes:
840057
1002945
J'ai besoin que le résultat soit (4 derniers caractères):
0057
2945
Ma ligne de code originale utilisait Regex.Replace mais je n’ai pas trouvé de regex au travail comme vous pouvez le voir dans les commentaires ci-dessous.
replacementVal = Regex.Replace(replacementVal, wildcard.Regex, wildcard.RegexReplaceBy);
J'ai changé mon code pour utiliser Regex.Match et ensuite le regex (?s)[0-9]{4}$
fonctionnait parfaitement (voir ci-dessous):
replacementVal = Regex.Replace(replacementVal, wildcard.Regex, wildcard.RegexReplaceBy);
Cependant, l'utilisation de Regex.Match rompt d'autres expressions régulières que j'utilise, par exemple, j'utilise ^(.).*
pour extraire la première lettre d'un nom. Cela fonctionne lorsque vous utilisez Regex.Replace, mais échoue lorsque vous utilisez Regex.Match.
Mon code est ci-dessous, notez la ligne d'origine contenant Regex.Replace est commentée.
Pourquoi Regex.Match fonctionne-t-il avec une expression et Regex.Replace avec une autre?
/// Replaces a wildcard in a string
/// </summary>
/// <param name="str">The string for which to replace the wildcards</param>
/// <param name="row">The DataRow in which the string exists</param>
/// <param name="wildcard">The wildcard to replace</param>
/// <returns>The string with the wildcard replaced</returns>
private static string ReplaceWildcardInString(string str, DataRow row, Wildcard wildcard)
{
// If the string is null or empty, return it as is
if (string.IsNullOrEmpty(str))
return str;
// This will hold the replacement value
var replacementVal = string.Empty;
// If the replacement column value is not empty
if (!row.IsDBNullOrNull(wildcard.ReplaceByColumnName))
{
// Convert its value to string
replacementVal = row[wildcard.ReplaceByColumnName].ToString();
// Apply wildcard regex if given
if (!string.IsNullOrEmpty(wildcard.Regex) && wildcard.RegexReplaceBy != null)
//replacementVal = Regex.Replace(replacementVal, wildcard.Regex, wildcard.RegexReplaceBy);
replacementVal = Regex.Match(replacementVal, wildcard.Regex).Value;
}
// Replace all wildcards with the replacement value (case insensitive)
var wildcardPattern = Regex.Escape(string.Format("%{0}%", wildcard.Name));
str = Regex.Replace(str, wildcardPattern, replacementVal, RegexOptions.Singleline | RegexOptions.IgnoreCase);
// Return the new string
return str;
}
Merci beaucoup, j'apprécie l'aide.
La méthode Regex.Replace
remplace toutes les sous-chaînes ne se chevauchant pas qui correspondent à un modèle d'expression régulière avec un remplacement spécifié.
La méthode Regex.Match
recherche dans la chaîne d'entrée spécifiée la première occurrence de l'expression régulière.
Ainsi, lorsque vous avez une chaîne comme 1002945
et que vous voulez obtenir exactement 4 chiffres à partir de la fin, vous pouvez utiliser
var result = Regex.Replace("1002945", @".*([0-9]{4})$", "$1", RegexOptions.Singleline);
ou
var matchResult = Regex.Match("1002945", @"[0-9]{4}$");
if (matchResult.Success)
{
Console.WriteLine(matchResult.Value);
}
Lorsque vous remplacez, vous devez faire correspondre toute la chaîne, ne faites correspondre et capture que les quatre derniers caractères qui sont des chiffres et affirmez que l'index des expressions rationnelles se trouve à la fin de la chaîne ($
). Notez que l'utilisation de l'option RegexOptions.Singleline
permet à .
de correspondre au caractère newline, auquel il ne correspond pas par défaut. La chaîne de remplacement doit être $1
, la référence de remplacement du premier groupe de capture qui capture les chiffres.
Lorsque vous utilisez Regex.Match("1002945", @"[0-9]{4}$").Value
, vous faites correspondre les 4 chiffres suivis de la fin de la chaîne ou d’une nouvelle ligne et de la fin de la chaîne (c’est parce que $
correspond de cette manière, si vous ne souhaitez pas autoriser une correspondance avant une chaîne). retour à la ligne et fin de chaîne, utilisez \z
manchor). Lorsque la correspondance est obtenue, vous pouvez vérifier le succès ou l'échec à l'aide de matchResult.Success
et, le cas échéant, obtenir le matchResult.Value
. Vous n'avez plus besoin de RegexOptions.Singleline
puisqu'il n'y a pas de .
dans l'expression régulière.
.*(?=.{4})$
correspondra aux quatre derniers caractères de la chaîne. Si vous remplacez cette correspondance par String.Empty
, il ne reste que ces quatre caractères.
Si la chaîne contient moins de quatre caractères, ils resteront dans la chaîne car l'expression régulière ne correspondra pas du tout, il n'y a donc rien à remplacer.
Vous n'avez pas besoin d'utiliser regex à cette fin.
string MyLast4Characters = MyString.Substring(((MyString.Length >= 4) ? (MyString.Length - 4) : (0)));
Cette partie ((MyString.Length >= 4) ? (4) : (0))
est faite pour vérifier si la chaîne d'origine est plus longue ou égale à 4 caractères, elle retournera ensuite les 4 derniers caractères, sinon la chaîne entière
Si cela doit être regex, je pense que vous voulez: .{4}(?=\s|$)
Mais je conviens que les expressions rationnelles ne sont probablement pas la meilleure solution ici.
Une dépression:
. : any character
{4} : exacty four times
(?= : followed by
\s : white space
| : or
$ : a line ending
) : end the followed by section
Je voudrais utiliser la méthode Regex.Match
.
Il ne correspond qu'à ce dont vous avez besoin.
Vous pouvez l'utiliser de deux manières.
string str = "asdf 12345";
if (str.Length > 4)
{
// Abbreviated ..
Console.WriteLine( "{0}", Regex.Match(str, @"(?s).{5}$").Value );
// Verbose ...
Regex rx = new Regex(@"(?s).{5}$");
str = rx.Match(str).Value;
Console.WriteLine( "{0}", str );
}
else {} // Do something else
Sortie
12345
12345
vous pouvez essayer d'utiliser Reverse()
à cette fin
Par exemple:-
string input = "1002945";
string rev = new string(input.Reverse().ToArray());
string res = null;
Match match = Regex.Match(rev, @"\d{4}");
if (match != null && !String.IsNullOrEmpty(match.Value))
{
res = new string(match.Value.Reverse().ToArray());
}
sortie:-
2945
J'utiliserais Regex.Match autant que possible avec les groupes correspondants:
string str = "Hello :) 1002945";
string pattern = @"(.).*(\d{4})$";
Match match = Regex.Match(str, pattern);
if (match.Success)
{
string firstChar = match.Groups[1].Value;
string lastNumber = match.Groups[2].Value;
Console.WriteLine("First character : " + firstChar);
Console.WriteLine("Last number : " + lastNumber);
}
Sortie:
First character : H
Last number : 2945
Je suppose que ceci est quelque chose avec votre RegexOptions
. Dans mon exemple, j'utilise le mode SingleLine
((?s)
) et la chaîne multiligne:
static void RegexTest()
{
string str = "i am long string\r\nwith the number 1002945";
string pattern = @"(?s)[0-9]{4}$"; // or @"(?s).{4}$"
string num = Regex.Match(str, pattern).Value;
}