Получение подстроки текста, содержащего теги HTML - PullRequest
4 голосов
/ 17 апреля 2009

Получение подстроки текста, содержащей теги HTML

Предположим, вам нужны первые 10 символов из следующего:

"

это пункт 1

это пункт 2

"

Вывод будет:

"

это"

Возвращаемый текст содержит незамкнутый тег P. Если это отображается на странице, последующее содержимое будет зависеть от открытого тега P. В идеале предпочтительный вывод должен закрывать все незакрытые теги HTML в обратном порядке, когда они были открыты:

"

это

" Мне нужна функция, которая возвращает подстроку HTML, следя за тем, чтобы никакие теги не оставались незамеченными

Ответы [ 5 ]

3 голосов
/ 17 апреля 2009

Вы должны научить свой код понимать, что ваша строка на самом деле является HTML или XML. Простое обращение с ней как со строкой не позволит вам работать с ней так, как вы хотите. Это означает сначала преобразовать его в правильный формат, а затем работать с этим форматом.

Использовать таблицу стилей XSL

Если ваш HTML является правильно сформированным XML, загрузите его в XMLDocument и запустите через таблицу стилей XSL, которая выполняет что-то вроде следующего:

<xsl:template match="p">
  <xsl:value-of select="substring(text(), 0, 10)" />
</xsl:template>

Использовать парсер HTML

Если это не правильно сформированный XML (как в вашем примере, где у вас неожиданно </p> в середине), вам нужно будет использовать HTML-анализатор некоторого вида , такой как HTML Agility Pack (см. Этот вопрос о синтаксических анализаторах C # HTML ).

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

2 голосов
/ 06 апреля 2011

Вы можете использовать следующую статическую функцию. Для рабочего примера проверьте: http://www.koodr.com/item/438c2e9c-62a8-45fc-9ca2-db1479f412e1. Вы также можете превратить это в метод расширения.

public static string HtmlSubstring (string html, int maxlength) {
//initialize regular expressions
string htmltag = "</?\\w+((\\s+\\w+(\\s*=\\s*(?:\".*?\"|'.*?'|[^'\">\\s]+))?)+\\s*|\\s*)/?>";
string emptytags = "<(\\w+)((\\s+\\w+(\\s*=\\s*(?:\".*?\"|'.*?'|[^'\">\\s]+))?)+\\s*|\\s*)/?></\\1>";

//match all html start and end tags, otherwise get each character one by one..
var expression = new Regex(string.Format("({0})|(.?)", htmltag)); 
MatchCollection matches = expression.Matches(html);

int i = 0;
StringBuilder content = new StringBuilder();
foreach (Match match in matches)
{
    if (match.Value.Length == 1
        && i < maxlength) 
    {                    
        content.Append(match.Value);
        i++; 
    }
    //the match contains a tag
    else if (match.Value.Length > 1) 
        content.Append(match.Value);
}

return Regex.Replace(content.ToString(), emptytags, string.Empty); }
1 голос
/ 17 апреля 2009

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

Одним из решений может быть:

а. Найдите текст между тегами <p> и </p>. Вы можете использовать следующее регулярное выражение для этого или использовать простой поиск строки:

\<p\>(.*?)\</p\>

б. В найденном тексте примените Substring(), чтобы извлечь необходимый текст.

с. Поместите извлеченный текст между тегами <p> и </p>.

0 голосов
/ 28 декабря 2012

попробуйте этот код (python 3.x):

notags=('img','br','hr')
def substring2(html,size):
    if len(html) <= size:
        return html
    result,tag,count='','',0
    tags=[]
    for c in html:
        result += c
        if c == '<':
            intag=True
        elif c=='>':
            intag=False
            tag=tag.split()[0]
            if tag[0] == '/':
                tag = tag.replace('/','')
                if tag not in notags:
                    tags.pop()
            else:
                if tag[-1] != '/' and tag not in notags:
                    tags.append(tag)
            tag=''
        else:
            if intag: 
                tag += c
            else:
                count+=1
                if count>=size: break
    while len(tags)>0:
        result += '</{0}>'.format(tags.pop())
    return result

s='<div class="main">html <code>substring</code> function written by <span>imxylz</span>, using <a href="http://www.python.org">python</a> language</div>'
print(s)
for size in (30,40,55):
    print(substring2(s,size))

выход

<div class="main">html <code>substring</code> function written by <span>imxylz</span>, using <a href="http://www.python.org">python</a> language</div>
<div class="main">html <code>substring</code> function writte</div>
<div class="main">html <code>substring</code> function written by <span>imxyl</span></div>
<div class="main">html <code>substring</code> function written by <span>imxylz</span>, using <a href="http://www.python.org">python</a></div>

1012 * более *

См. Код в github .

Другой вопрос .

0 голосов
/ 17 апреля 2009

Вы можете перебрать строку html, чтобы обнаружить угловые скобки и создать массив тегов и определить, есть ли соответствующий закрывающий тег для каждого из них. Проблема в том, что HTML допускает закрывающие теги, такие как img, br, meta, поэтому вам нужно знать о них. Вам также необходимо иметь правила для проверки порядка закрытия, потому что простое сопоставление открытия с закрытием не делает корректным HTML - если вы открываете div, затем ap, затем закрываете div и затем закрываете p, то есть не действителен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...