Как получить соответствие внутренних цветовых меток с помощью Regex? - PullRequest
0 голосов
/ 10 октября 2019

У меня есть одна проблема, какой шаблон я должен использовать, чтобы найти все теги цветов расширенного текста в других цветовых тегах?

Так, например, у меня есть такой ввод:

<color=yellow>Hello <color=cyan>World!</color></color>

Иудалите, заменив пустые строковые совпадающие теги, и получите это в качестве входных данных после:

<color=yellow>Hello World!</color>

Это может быть еще больше тегов, например:

<color=yellow>Hello my <color=cyan>name</color> is <color=gray>Kite <color=white>Watson!</color></color></color>

И иметь это после:

<color=yellow>Hello my name is Kite Watson!</color>

Причина, по которой мне это нужно, заключается в том, что я использую Regex для применения подсветки кода к тексту в текстовом поле, а некоторые ключевые слова раскрашиваются в комментариях, как в примере ниже

enter image description here

Поэтому я хочу проверить и удалить, есть ли какие-либо цветовые теги внутри цветовых тегов, как в этом примере комментария.

Я довольно новичок в Regex, поэтомув данный момент немного растерялся и не уверен что делать. Может кто-нибудь дать мне совет, как мне это сделать? :) Спасибо!

Ответы [ 2 ]

1 голос
/ 10 октября 2019

Удалите все теги, кроме первого и последнего, и вы получите то, что вы хотите, используя следующее регулярное выражение,

(?<!^)<[^>]*>(?!$)

Это в основном совпадает со всеми тегами, кроме первого и последнего, используя отрицательный взгляд вокруг. Дайте мне знать, если это работает для вашего сценария, иначе я смогу усилить регулярное выражение.

Проверьте это демо

0 голосов
/ 10 октября 2019

Я пошел с немного другим подходом.

    Regex tags = new Regex(@"<color=#.*?>|<\/color>");
    MatchCollection matches = tags.Matches(c);

    bool hasStarted = false;
    int innerTags = 0;

    const string tempStart = "¬¬¬¬¬¬¬Â";
    const string tempEnd = "Â~Â~Â~Â~";
    foreach (Match match in matches)
    {
        if (match.Value.Contains("<color=#"))
        {
            if (hasStarted)
            {
                var cBuilder = new StringBuilder(c);
                cBuilder.Remove(match.Index, match.Length);
                cBuilder.Insert(match.Index, tempStart);

                c = cBuilder.ToString();

                innerTags++;
            }
            else
            {
                hasStarted = true;
            }
        }
        else if (match.Value.Equals("</color>"))
        {
            if (innerTags > 0)
            {
                var cBuilder = new StringBuilder(c);
                cBuilder.Remove(match.Index, match.Length);
                cBuilder.Insert(match.Index, tempEnd);

                c = cBuilder.ToString();

                innerTags--;
            }
            else if (innerTags <= 0)
            {
                hasStarted = false;
            }
        }
    }
    c = c.Replace(tempStart, string.Empty);
    c = c.Replace(tempEnd, string.Empty);

Не уверен, что это лучший способ, но он работает довольно хорошо.

...