J'ai une ficelle comme:
"super exemple of string key : text I want to keep - end of my string"
Je veux juste garder la chaîne qui est entre "key : "
et " - "
. Comment puis je faire ça? Dois-je utiliser un regex ou puis-je le faire d'une autre manière?
Peut-être qu’un bon moyen est simplement de découper une sous-chaîne :
String St = "super exemple of string key : text I want to keep - end of my string";
int pFrom = St.IndexOf("key : ") + "key : ".Length;
int pTo = St.LastIndexOf(" - ");
String result = St.Substring(pFrom, pTo - pFrom);
string input = "super exemple of string key : text I want to keep - end of my string";
var match = Regex.Match(input, @"key : (.+?)-").Groups[1].Value;
ou avec juste des opérations de chaîne
var start = input.IndexOf("key : ") + 6;
var match2 = input.Substring(start, input.IndexOf("-") - start);
Vous pouvez le faire sans regex
input.Split(new string[] {"key :"},StringSplitOptions.None)[1]
.Split('-')[0]
.Trim();
En fonction de la robustesse/flexibilité de votre implémentation, cela peut s'avérer un peu délicat. Voici l'implémentation que j'utilise:
public static class StringExtensions {
/// <summary>
/// takes a substring between two anchor strings (or the end of the string if that anchor is null)
/// </summary>
/// <param name="this">a string</param>
/// <param name="from">an optional string to search after</param>
/// <param name="until">an optional string to search before</param>
/// <param name="comparison">an optional comparison for the search</param>
/// <returns>a substring based on the search</returns>
public static string Substring(this string @this, string from = null, string until = null, StringComparison comparison = StringComparison.InvariantCulture)
{
var fromLength = (from ?? string.Empty).Length;
var startIndex = !string.IsNullOrEmpty(from)
? @this.IndexOf(from, comparison) + fromLength
: 0;
if (startIndex < fromLength) { throw new ArgumentException("from: Failed to find an instance of the first anchor"); }
var endIndex = !string.IsNullOrEmpty(until)
? @this.IndexOf(until, startIndex, comparison)
: @this.Length;
if (endIndex < 0) { throw new ArgumentException("until: Failed to find an instance of the last anchor"); }
var subString = @this.Substring(startIndex, endIndex - startIndex);
return subString;
}
}
// usage:
var between = "a - to keep x more stuff".Substring(from: "-", until: "x");
// returns " to keep "
Regex est exagéré ici.
Vous pouvez utilisez string.Split
avec la surcharge qui prend un string[]
pour les délimiteurs, mais cela serait aussi excessif.
Regardez Substring
et IndexOf
- le premier pour obtenir les parties d'une chaîne données et index, ainsi qu'une longueur et le second pour rechercher des chaînes/caractères internes indexés.
Voici comment je peux faire ça
public string Between(string STR , string FirstString, string LastString)
{
string FinalString;
int Pos1 = STR.IndexOf(FirstString) + FirstString.Length;
int Pos2 = STR.IndexOf(LastString);
FinalString = STR.Substring(Pos1, Pos2 - Pos1);
return FinalString;
}
Je pense que cela fonctionne:
static void Main(string[] args)
{
String text = "One=1,Two=2,ThreeFour=34";
Console.WriteLine(betweenStrings(text, "One=", ",")); // 1
Console.WriteLine(betweenStrings(text, "Two=", ",")); // 2
Console.WriteLine(betweenStrings(text, "ThreeFour=", "")); // 34
Console.ReadKey();
}
public static String betweenStrings(String text, String start, String end)
{
int p1 = text.IndexOf(start) + start.Length;
int p2 = text.IndexOf(end, p1);
if (end == "") return (text.Substring(p1));
else return text.Substring(p1, p2 - p1);
}
ou, avec une regex.
using System.Text.RegularExpressions;
...
var value =
Regex.Match(
"super exemple of string key : text I want to keep - end of my string",
"key : (.*) - ")
.Groups[1].Value;
avec un exemple courant .
Vous pouvez décider si c'est exagéré.
comme méthode d'extension sous validée
using System.Text.RegularExpressions;
public class Test
{
public static void Main()
{
var value =
"super exemple of string key : text I want to keep - end of my string"
.Between(
"key : ",
" - ");
Console.WriteLine(value);
}
}
public static class Ext
{
static string Between(this string source, string left, string right)
{
return Regex.Match(
source,
string.Format("{0}(.*){1}", left, right))
.Groups[1].Value;
}
}
string str="super exemple of string key : text I want to keep - end of my string";
int startIndex = str.IndexOf("key") + "key".Length;
int endIndex = str.IndexOf("-");
string newString = str.Substring(startIndex, endIndex - startIndex);
Une solution LINQ opérationnelle:
string str = "super exemple of string key : text I want to keep - end of my string";
string res = new string(str.SkipWhile(c => c != ':')
.Skip(1)
.TakeWhile(c => c != '-')
.ToArray()).Trim();
Console.WriteLine(res); // text I want to keep
Puisque le :
et le -
sont uniques, vous pouvez utiliser:
string input;
string output;
input = "super example of string key : text I want to keep - end of my string";
output = input.Split(new char[] { ':', '-' })[1];
Vous pouvez utiliser la méthode d'extension ci-dessous:
public static string GetStringBetween(this string token, string first, string second)
{
if (!token.Contains(first)) return "";
var afterFirst = token.Split(new[] { first }, StringSplitOptions.None)[1];
if (!afterFirst.Contains(second)) return "";
var result = afterFirst.Split(new[] { second }, StringSplitOptions.None)[0];
return result;
}
L'utilisation est:
var token = "super exemple of string key : text I want to keep - end of my string";
var keyValue = token.GetStringBetween("key : ", " - ");
J'ai utilisé l'extrait de code de Vijay Singh Rana, qui fait essentiellement le travail. Mais cela pose des problèmes si la firstString
contient déjà la lastString
. Ce que je voulais, c'était extraire un access_token d'une réponse JSON (aucun analyseur JSON chargé). Mon firstString
était \"access_token\": \"
et mon lastString
était \"
. J'ai fini avec une petite modification
string Between(string str, string firstString, string lastString)
{
int pos1 = str.IndexOf(firstString) + firstString.Length;
int pos2 = str.Substring(pos1).IndexOf(lastString);
return str.Substring(pos1, pos2);
}
Vous avez déjà de bonnes réponses et je réalise que le code que je fournis est loin d’être le plus efficace et le plus propre. Cependant, j'ai pensé que cela pourrait être utile à des fins éducatives. Nous pouvons utiliser des classes et des bibliothèques prédéfinies toute la journée. Mais sans comprendre le fonctionnement interne, nous imitons et répétons simplement et n'apprendrons jamais rien. Ce code fonctionne et est plus basique ou "vierge" que certains autres:
char startDelimiter = ':';
char endDelimiter = '-';
Boolean collect = false;
string parsedString = "";
foreach (char c in originalString)
{
if (c == startDelimiter)
collect = true;
if (c == endDelimiter)
collect = false;
if (collect == true && c != startDelimiter)
parsedString += c;
}
Vous vous retrouvez avec la chaîne souhaitée assignée à la variable parsedString. Gardez à l'esprit qu'il capturera également les espaces en cours et précédents. Rappelez-vous qu'une chaîne est simplement un tableau de caractères qui peut être manipulé comme d'autres tableaux avec index, etc.
Prends soin.
var matches = Regex.Matches(input, @"(?<=key :)(.+?)(?=-)");
Ceci ne renvoie que la ou les valeurs entre "key:" et l'occurrence suivante de "-"
Si vous recherchez une solution sur 1 ligne, voici le résultat:
s.Substring(s.IndexOf("eT") + "eT".Length).Split("97".ToCharArray()).First()
La solution complète sur 1 ligne, avec System.Linq
:
using System;
using System.Linq;
class OneLiner
{
static void Main()
{
string s = "TextHereTisImortant973End"; //Between "eT" and "97"
Console.WriteLine(s.Substring(s.IndexOf("eT") + "eT".Length)
.Split("97".ToCharArray()).First());
}
}
Comme je dis toujours rien n’est impossible:
string value = "super exemple of string key : text I want to keep - end of my string";
Regex regex = new Regex(@"(key \: (.*?) _ )");
Match match = regex.Match(value);
if (match.Success)
{
Messagebox.Show(match.Value);
}
J'espère que j'ai aidé.
.