Выделите целые слова, опустите HTML - PullRequest
2 голосов
/ 23 августа 2009

Я пишу некоторый код C # для разбора RSS-каналов и выделения целых слов в контенте, однако мне нужно выделять только те слова, которые находятся вне HTML. Пока что у меня есть:

string contentToReplace = "This is <a href=\"test.aspx\" alt=\"This is test content\">test</a> content";

string pattern = "\b(this|the|test|content)\b";

string output = Regex.Replace(contentToReplace, pattern, "<span style=\"background:yellow;\">$1</span>", RegexOptions.Singleline | RegexOptions.IgnoreCase);

Это отлично работает, за исключением того, что в теге alt будет выделено слово «тест». Я могу легко написать функцию, которая удаляет HTML, а затем выполняет замену, но мне нужно сохранить HTML для отображения содержимого.

Ответы [ 3 ]

2 голосов
/ 23 августа 2009

Если вход является допустимым XHTML / XML, вы можете проанализировать его в древовидную структуру (DOM / XLinq), рекурсивно пройтись по дереву, заменить все вхождения ключевых слов в текстовых узлах и, наконец, сериализировать древовидную структуру обратно в строку. 1001 *

Неопробованный псевдокод:

XNode Highlight(XElement element, List<string> keywords)
{
    var result = new XElement(element.Name);
    // copy element attributes to result

    foreach (var node in element)
    {
        if (node.Type == NodeType.Text)
        {
            var value = node.Value;
            // while value contains keyword
            // {
            //      add substring before keyword in value to result
            //      add new XElement with highlighted keyword to result
            //      remove consumed substring from value
            // }
        }
        else if (node.Type == NodeType.Element)
        {
            result.Add(Highlight((XElement)node, keywords));
        }
        else
        {
            result.Add(node);
        }
    }

    return result;
}

var output = Highlight(XElement.Parse(input), new List<string> {...}).ToString();
1 голос
/ 23 августа 2009

Другое решение, если у вас есть действительный XML, но вы не хотите его анализировать: сначала разбейте входную строку на части так, чтобы каждая часть содержала только тег или текст, но не оба. Например:

"This is ",
"<a href=\"test.aspx\" alt=\"This is test content\">",
"test"
"</a>"
" content"

Затем выполните итерации по частям и примените свое регулярное выражение только к строкам, которые не начинаются с '<'. Наконец, объедините все части обратно в одну строку.

0 голосов
/ 23 августа 2009

Вот основной.

private void Form1_Load(object sender, EventArgs e)
    {
        string contentToReplace = "This is <a href=\"test.aspx\" alt=\"This is test content\"> hello test world</a> content";

        string pattern = @"(>{1}.*)(test)(.*<{1})";

        string output = Regex.Replace(contentToReplace, pattern, "$1<span>$2</span>$3", RegexOptions.Singleline | RegexOptions.IgnoreCase);

        //output is :
        //This is <a href="test.aspx" alt="This is test content"> hello <span>test</span> world</a> content


        MessageBox.Show(output);
        Close();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...