Подтвердить что ты не робот

Как удалить только некоторые подстроки из строки?

Используя С#, у меня есть строка, которая представляет собой SQL script, содержащий несколько запросов. Я хочу удалить разделы строки, заключенные в одинарные кавычки. Я могу сделать это, используя Regex.Replace следующим образом:

string test = "Only 'together' can we turn him to the 'dark side' of the Force";
test = Regex.Replace(test, "'[^']*'", string.Empty);

Результаты в: "Только мы можем превратить его в Силу"

Что я хочу сделать, это удалить подстроки между кавычками EXCEPT для подстрок, содержащих определенную подстроку. Например, используя приведенную выше строку, я хочу удалить цитированные подстроки, кроме тех, которые содержат "темные", так что результирующая строка:

Результаты: "Только мы можем превратить его в" темную сторону "Силы"

Как это можно сделать с помощью Regex.Replace или, возможно, с помощью какой-либо другой техники? В настоящее время я пытаюсь использовать решение, использующее Substring(), IndexOf() и Contains().

Примечание. Мне все равно, удалены ли одиночные кавычки вокруг "темной стороны" или нет, поэтому результат также может быть: "Только мы можем превратить его в темную сторону Силы". Я говорю это, потому что решение с использованием Split() удалит все одинарные кавычки.

Изменить: У меня еще нет решения, используя Substring(), IndexOf() и т.д. Под "работой" я имею в виду, что я думаю в голове, как это может быть сделанный. У меня нет кода, поэтому я еще не опубликовал его. Спасибо.

Изменить: Решение VKS ниже работает. Я не избежал первой попытки, поэтому она не удалась. Кроме того, это не сработало, если я не включил одиночные кавычки вокруг всей строки.

test = Regex.Replace(test, "'(?![^']*\\bdark\\b)[^']*'", string.Empty);
4b9b3361

Ответ 1

'(?![^']*\bdark\b)[^']*'

Попробуйте this.See demo.Replace by empty string. Вы можете использовать lookahead здесь, чтобы проверить, содержит ли '' слово dark.

https://www.regex101.com/r/rG7gX4/12

Ответ 2

В то время как vks-решение работает, я хотел бы продемонстрировать другой подход:

string test = "Only 'together' can we turn him to the 'dark side' of the Force";
test = Regex.Replace(test, @"'[^']*'", match => {
    if (match.Value.Contains("dark"))
        return match.Value;

    // You can add more cases here

    return string.Empty;
});

Или, если ваше условие достаточно просто:

test = Regex.Replace(test, @"'[^']*'", match => match.Value.Contains("dark")
    ? match.Value
    : string.Empty
);

То есть, используйте лямбда для обеспечения обратного вызова для замены. Таким образом, вы можете запустить произвольную логику для замены строки.

Ответ 3

что-то вроде этого будет работать.
вы можете добавить все строки, которые хотите сохранить в массиве excludedStrings

        string test = "Only 'together' can we turn him to the 'dark side' of the Force";

        var excludedString = new string[] { "dark side" };

        int startIndex = 0;

        while ((startIndex = test.IndexOf('\'', startIndex)) >= 0)
        {
            var endIndex = test.IndexOf('\'', startIndex + 1);
            var subString = test.Substring(startIndex, (endIndex - startIndex) + 1);
            if (!excludedString.Contains(subString.Replace("'", "")))
            {
                test = test.Remove(startIndex, (endIndex - startIndex) + 1);
            }
            else
            {
                startIndex = endIndex + 1;
            }
        }

Ответ 4

Я сделал эту попытку, о которой, я думаю, вы думали (какое-то решение использует split, Contain,... без regex)

string test = "Only 'together' can we turn him to the 'dark side' of the Force";
string[] separated = test.Split('\'');

string result = "";

for (int i = 0; i < separated.Length; i++)
{
    string str = separated[i];
    str = str.Trim();   //trim the tailing spaces

    if (i % 2 == 0 || str.Contains("dark")) // you can expand your condition
    {
       result += str+" ";  // add space after each added string
    }
}
result = result.Trim(); //trim the tailing space again

Ответ 5

Другой метод с помощью оператора чередования регулярных выражений |.

@"('[^']*\bdark\b[^']*')|'[^']*'"

Затем замените соответствующий символ на $1

DEMO

string str = "Only 'together' can we turn him to the 'dark side' of the Force";
string result = Regex.Replace(str, @"('[^']*\bdark\b[^']*')|'[^']*'", "$1");
Console.WriteLine(result);

IDEONE

Объяснение:

  • (...) называется группа захвата.

  • '[^']*\bdark\b[^']*' будет соответствовать всем одиночным кавычками, содержащим подстроку dark. [^']* соответствует любому символу, но не ', ноль или более раз.

  • ('[^']*\bdark\b[^']*'), поскольку регулярное выражение находится в группе захвата, все совпадающие символы хранятся внутри индекса группы.

  • | Далее идет регулярное выражение оператор чередования.

  • '[^']*' Теперь это соответствует всем оставшимся (кроме тем, что содержит dark) одинарные кавычки. Обратите внимание, что это не будет соответствовать одиночной кавычки, которая содержит подстроку dark, потому что мы уже сопоставляли эти строки с шаблоном ранее перед оператором чередования |.

  • Наконец, заменив все совпадающие символы символами внутри группы, индекс 1 даст вам желаемый результат.