Як замінити певну появу рядка у рядку?

У мене є рядок, який може містити "title1" двічі в ньому.

наприклад,

server/api/shows?title1=its always sunny in philadelphia&title1=breaking bad ...

Мені потрібно змінити другий екземпляр слова "title1" на "title2"

Я вже знаю, як визначити, чи є два рядки в рядку.

int occCount = Regex.Matches(callingURL, "title1=").Count;

if (occCount > 1)
{
     //here's where I need to replace the second "title1" to "title2"
}

Я знаю, що ми, ймовірно, можемо використовувати Regex тут, але я не можу отримати заміни на другій інстанції. Чи може хто-небудь дати мені руку?

7
це НІКОЛИ не матиме більше двох випадків
додано Автор Rj., джерело
Я перевіряю, щоб рядок ніколи не міг мати більше двох випадків. зовнішня рядок будується на виборах користувача на екрані, і я враховую правильні вибори ...
додано Автор Rj., джерело
ви знаєте стару вимову НІКОЛИ ніколи не повідомляйте
додано Автор MethodMan, джерело
якщо є 3 приклади слова title1 , то треба змінити третє на title3 ?
додано Автор Sam I am, джерело
Це звучить як більш широка проблема для мене.
додано Автор Dan Teesdale, джерело

7 Відповіді

Це замінить лише другий екземпляр title1 (та будь-яких наступних випадків) після першого:

string output = Regex.Replace(input, @"(?<=title1.*)title1", "title2");

Однак, якщо є більше двох примірників, можливо, це не те, що ви хочете. Це трохи сирий, але ви можете зробити це для вирішення будь-якої кількості випадків:

int i = 1;
string output = Regex.Replace(input, @"title1", m => "title" + i++);
12
додано
щось на зразок цього: server/api/Shows? title1 = breaking% 20bad & title2 = two% 20and% 20a% & zwnj; 20half% 20men & episode & title = 1 пілот і епізод & zwnj; title2 = a% 20big% 20bag & zwnj;% 20of% 20dog
додано Автор Rj., джерело
pswg, я знаю, що я вже прийняв вашу відповідь, але я просто намагався зробити те саме, але словом "episodetitle1", і це не дає мені тих же результатів. Забезпечувати іншу руку? callingURL = Regex.Replace (callingURL, @ "(? <= episodetitle1. *) episodetitle1", "episodetitle2");
додано Автор Rj., джерело
це зробило трюк. спасибі пане!
додано Автор Rj., джерело
Я перевіряю це зараз
додано Автор Rj., джерело
@ Rj Що таке рядок введення?
додано Автор p.s.w.g, джерело
@ Rj Ну, схоже, що ця рядок вже замінила другий episodetitle1 з episodetitle2 , але в будь-якому випадку цей шаблон працює для мене, чи використовуєте ви title1 або episodetitle1 .
додано Автор p.s.w.g, джерело

ви можете вказати кількість і індекс, щоб почати пошук у

string str = @"server/api/shows?title1=its always sunny in philadelphia&title1=breaking bad ...";

Regex regex = new Regex(@"title1");
str = regex.Replace(str, "title2", 1, str.IndexOf("title1") + 6);
2
додано
Якраз те, що мені потрібно - не вдалося знайти його в статичному API. Я розчарований тим, що статичний метод з тим самим ім'ям не містить цієї основної функції; це змусило мене повірити, що API це не вистачало. IMHO - чудовий приклад того, як не слід перевантажувати імена методів, якщо ви збираєтесь повторно застосувати статичний/нестатистичний метод з різними наборами функцій.
додано Автор Adam, джерело
Це хороший підхід, але чому б ви використали регулярний вираз на останньому кроці? Ви можете просто зробити string.Replace .
додано Автор p.s.w.g, джерело
Ні, ти маєш рацію. Вам слід зробити першу пару string.Substring (як-от одну відповідь, яка зараз вилучена).
додано Автор p.s.w.g, джерело
@ p.s.w.g чи string.Replace має поле, вказуючи, де ви починаєте пошук?
додано Автор Sam I am, джерело

Ви, можливо, можете скористатися негативним виглядом обличчя:

title1(?!.*title1)

І замінити на title2 .

Дізнайтеся, як працює тут .

1
додано
Що робити, якщо воно має одне заголовок ... Ви замінюєте неправильний
додано Автор Anirudha, джерело
він каже, що ніколи не буде більше двох випадків ..
додано Автор Anirudha, джерело
це може мати єдине явище
додано Автор Anirudha, джерело
Гм .... Так що?
додано Автор Jerry, джерело
@Anirudh Користувач вже переконався, що з if існує два примірника title1 .
додано Автор Jerry, джерело

Ось метод розширення C#, який я створив для аналогічного завдання, який може стати в нагоді.

internal static class ExtensionClass
{
    public static string ReplaceNthOccurance(this string obj, string find, string replace, int nthOccurance)
    {
        if (nthOccurance > 0)
        {
            MatchCollection matchCollection = Regex.Matches(obj, Regex.Escape(find));
            if (matchCollection.Count >= nthOccurance)
            {
                Match match = matchCollection[nthOccurance - 1];
                return obj.Remove(match.Index, match.Length).Insert(match.Index, replace);
            }
        }
        return obj;
    }
}

Тоді ви можете використовувати його з наступним прикладом.

"computer, user, wАБОkstation, description".ReplaceNthOccurance(",", ", and", 3)

Що дасть наступне.

"computer, user, wАБОkstation, and description"

АБО

"computer, user, wАБОkstation, description".ReplaceNthOccurance(",", " АБО", 1).ReplaceNthOccurance(",", " and", 2)

Виведемо нижче.

"computer АБО user, wАБОkstation and description"

Я сподіваюсь, що це допомагає іншому, хто має таке ж питання.

1
додано

Шлях P.S.W.G дійсно був чудовим. але нижче я згадав про один простий спосіб зробити це для тих, хто має проблеми з виразом лямбда і регулярного виразу ..;)

int index = input.LastIndexOf ("title1 =");

string output4 = input.Substring(0, index - 1) + "&title2" + input.Substring(index + "title1".Length, input.Length - index - "title1".Length);

0
додано

Ви можете використовувати регулярний вираз, замінити MatchEvaluator і надати йому "стан":

string callingURL = @"server/api/shows?title1=its always sunny in philadelphia&title1=breaking bad";

int found = -1;
string callingUrl2 = Regex.Replace(callingURL, "title1=", x =>
{
    found++;
    return found == 1 ? "title2=" : x.Value;
});

Заміна може бути єдиним шляхом використання оператора postfixed ++ (зовсім нечитабельна).

string callingUrl2 = Regex.Replace(callingURL, "title1=", x => found++ == 1 ? "title2=" : x.Value);
0
додано

Я знайшов цю посилання одразу ж в пошуку Google.

C# - indexВід n-го появу рядка?

Отримайте індекс від першої появи рядка.

Використовуйте ReturnIndex +1 для вихідної позиції другого IndexOf.

Вкладіть його в два рядки у відповідному індексі символу "1".

Зверніть його назад разом із символом "2".

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

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