Отримати рядок між двома рядками в рядку

Я маю рядок типу:

"super exemple of string key : text I want to keep - end of my string"

Я просто хочу зберегти рядок, який знаходиться між "key:" і "-" . Як я можу це зробити? Чи повинен я використовувати Regex або я можу робити це іншим способом?

59
використовуйте підрядок і indexof
додано Автор Sayse, джерело
Отримати рядок після певного рядка в рядку і перед іншою певною ланцюжком, який також міститься в рядку, де знаходиться рядок ..
додано Автор Ken Kin, джерело

15 Відповіді

Можливо, хорошим способом є просто вирізати підрядок:

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);
89
додано
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;

або просто операціями з рядками

var start = input.IndexOf("key : ") + 6;
var match2 = input.Substring(start, input.IndexOf("-") - start);
25
додано

Ви можете зробити це без регулярного виразу

 input.Split(new string[] {"key :"},StringSplitOptions.None)[1]
      .Split('-')[0]
      .Trim();
18
додано

Залежно від того, наскільки надійною/гнучкою ви хочете, щоб ваша реалізація була, це може бути трохи складніше. Ось реалізація, яку я використовую:

public static class StringExtensions {
    /// 
/// takes a substring between two anchor strings (or the end of the string if that anchor is null) ///
 
    /// 
a string
    /// 
an optional string to search after
    /// 
an optional string to search before
    /// 
an optional comparison for the search
    /// a substring based on the search
    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 "
11
додано
@Leon: ви повинні мати можливість вирвати всі пов'язані з культурою речі, а .NET просто використовувати поточну культуру для операції indexOf. Хоча я не знайомий з універсальними додатками Windows, тому не можу сказати точно.
додано Автор ChaseMedallion, джерело
@AdrianIftode: хороший виклик. Це, безумовно, помилка. Має сенс почати пошук другого якоря на startIndex, оскільки це вже закінчується кінець першого якоря. Я виправив код тут.
додано Автор ChaseMedallion, джерело
InvariantCulture не працює з універсальними програмами Windows. Чи є спосіб видалити його з підтримкою функціональності вашого класу? @ChaseMedallion
додано Автор Leon, джерело
Я використовував ваш код, але я знайшов невелику помилку, коли в @ this.IndexOf (поки, startIndex + fromLength, порівняння) з рядків, як "AB", де A від і B до, так що я видалив + fromLength. Я не перевірив його глибоко
додано Автор Adrian Iftode, джерело

Тут Regex перебільшує.

Ви можете використовувати string.Split із перевантаженням, яке приймає рядок [] для роздільників, але це також бути надмірним.

Перегляньте Substring і IndexOf - перша для отримання частин заданого рядка та індексу та довжину і другу для пошуку індексованих внутрішніх рядків/символів.

10
додано
Це не надмірність ... насправді, я б сказав, що Substring та IndexOf є невдалими. Я б сказав, що string.Split - справа. Regex є надмірним.
додано Автор It'sNotALie., джерело
Це не повинно, якщо ви знаєте, як написати рег ...
додано Автор It'sNotALie., джерело
@Віддано О.
додано Автор It'sNotALie., джерело
@newStackExchangeInstance - я вважаю, що він говорить про string.Split .
додано Автор Oded, джерело
Справа в тому, що це перебільшення або недо-вбивство є спірним, тому що відповідь виконує прохання плакат про те, щоб зробити це іншим способом, ніж Regex.
додано Автор Karl Anderson, джерело
@newStackExchangeInstance: він також виходить з ладу, якщо перед "ключем" є "-". Substring є плямою.
додано Автор jmoreno, джерело

Ось як я можу це зробити

   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;
    }
8
додано

Я думаю, що це працює:

   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);                      
    }
7
додано
Відмінне рішення. Дякую!
додано Автор arcee123, джерело

або, з регулярним виразом.

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;

з прикладом виконання .

Можна вирішити, чи буде його зайвим.

або

як затверджений метод розширення

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.Fабоmat("{0}(.*){1}", left, right))
            .Groups[1].Value;
    }
}
5
додано
 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);
5
додано
Ваш код призведе до повернення двокрапки на початку newString.
додано Автор tsells, джерело

Робоче рішення LINQ:

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
3
додано
Це працює лише для односимвольних заповнювачів?
додано Автор beppe9000, джерело
супер просте рішення.
додано Автор Erdinç, джерело

Оскільки : і - унікальні, ви можете використовувати:

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];
3
додано
Ця відповідь не додає нічого значущого до вже великої кількості існуючих відповідей.
додано Автор Mephy, джерело

Нижче наведено спосіб розширення:

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;
    }

Використання:

var token = "super exemple of string key : text I want to keep - end of my string";
var keyValue = token.GetStringBetween("key : ", " - ");
2
додано

У вас вже є хороші відповіді, і я розумію, що код, який я надаю, далеко не найефективніший і найчистіший. Однак, я вважав, що це може бути корисним для освітніх цілей. Ми можемо використовувати вбудовані класи і бібліотеки протягом усього дня. Але без розуміння внутрішніх дій ми просто імітуємо і повторюємо і ніколи нічого не дізнаємося. Цей код працює і є більш базовим або "невинним", ніж деякі інші:

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;
}

Ви в кінцевому підсумку отримаєте потрібну рядок, призначений для змінної parsedString. Майте на увазі, що він також захоплюватиме проміжні та попередні пробіли. Пам'ятайте, що рядок - це просто масив символів, якими можна керувати, як інші масиви з індексами тощо.

Піклуватися.

1
додано
Я це зрозумів. Я просто вказував на свої сильні і тижневі бали. Хоча, щоб відповісти на початкове запитання, потрібно трохи більше, оскільки потрібно відповідати межі рядка, а не просто меж символів. Але ідея однакова.
додано Автор Paulo Morgado, джерело
Це найкращий алгоритм, хоча найгірший у створенні рядків. Усі надані відповіді, які не є тільки регулярними виразами, є спричиненими тригерами при створенні рядків, але це найгірше в цьому сенсі. Якщо ви тільки що захопили початок кінця рядка, щоб захопити і використати '' string.Substring '', щоб витягти його, це було б ідеально.
додано Автор Paulo Morgado, джерело
Я згоден. Як я вже згадував, це далеко не ефективно. Я б не рекомендував використовувати цей алгоритм. Це просто "зневажає", щоб він розумів рядки на більш низькому рівні.Якщо він просто хоче зробити роботу, він вже мав відповіді, які б цього досягли.
додано Автор flyNflip, джерело
Абсолютно Ви прямо на мету.
додано Автор flyNflip, джерело

Як я завжди кажу, ніщо неможливе:

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);
}

Пам'ятайте, що слід додати посилання на System.Text.RegularExpressions

Сподіваюся, що я допоміг.

0
додано
var matches = Regex.Matches(input, @"(?<=key :)(.+?)(?=-)");

Це повертає тільки значення (ів) між "ключем:" і наступним появою "-"

0
додано
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug