2008-12-11 2 views
7

Есть ли способ разделить длинную строку HTML после N слов? Очевидно, что я мог бы использовать:Разделить HTML после N слов в python

' '.join(foo.split(' ')[:n]) 

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

Мне нужно сделать это на сайте zope/plone - если в тех продуктах, которые могут это сделать, есть что-то стандартное, это будет идеально.

Например, у меня есть текст:

<p>This is some text with a 
    <a href="http://www.example.com/" title="Example link"> 
    bit of linked text in it 
    </a>. 
</p> 

И я прошу его разделить после 5 слов, он должен вернуть:

<p>This is some text with</p> 

7 слов:

<p>This is some text with a 
    <a href="http://www.example.com/" title="Example link"> 
    bit 
    </a> 
</p> 
+0

Вы хотите игнорировать теги, чтобы их не разделили? Другими словами, только получить и разделить текст, который не содержится в теге. – monkut 2008-12-11 17:03:32

+0

Вы хотите разделить текст документа, заключенный между тегами (например, между

и

тегами)? – gotgenes 2008-12-11 17:05:12

ответ

6

Посмотрите на функцию truncate_html_words в django.utils.text. Даже если вы не используете Django, код там делает именно то, что вы хотите.

3

Я слышал, что Beautiful Soup очень хорошо разбирается в html. Вероятно, он сможет помочь вам получить правильный html.

0

Я собирался упомянуть базу HTMLParser, которая построена на Python, так как я не уверен, что конечный результат, к которому вы пытаетесь добраться, может или не может быть там, вы будете работать с в основном

0

Вы можете использовать сочетание регулярных выражений, BeautifulSoup или Tidy (предпочитаю BeautifulSoup). Идея проста: сначала разделите все теги HTML. Найдите n-ое слово (n = 7 здесь), найдите количество раз, когда n-го слова появится в строке до тех пор, пока n слов - coz u не будут искать только последнее вхождение, которое будет использоваться для усечения.

Вот фрагмент кода, хотя и несколько хаотично, но работает

import re 
from BeautifulSoup import BeautifulSoup 
import tidy 

def remove_html_tags(data): 
    p = re.compile(r'<.*?>') 
    return p.sub('', data) 

input_string='<p>This is some text with a <a href="http://www.example.com/" '\ 
    'title="Example link">bit of linked text in it</a></p>' 

s=remove_html_tags(input_string).split(' ')[:7] 

###required to ensure that only the last occurrence of the nth word is                      
# taken into account for truncating.                              
# coz if the nth word could be 'a'/'and'/'is'....etc                          
# which may occur multiple times within n words                            
temp=input_string 
k=s.count(s[-1]) 
i=1 
j=0 
while i<=k: 
    j+=temp.find(s[-1]) 
    temp=temp[j+len(s[-1]):] 
    i+=1 
####                                       
output_string=input_string[:j+len(s[-1])] 

print "\nBeautifulSoup\n", BeautifulSoup(output_string) 
print "\nTidy\n", tidy.parseString(output_string) 

Выход, что и хотят

BeautifulSoup 
<p>This is some text with a <a href="http://www.example.com/" title="Example link">bit</a></p> 

Tidy 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN"> 
<html> 
<head> 
<meta name="generator" content= 
"HTML Tidy for Linux/x86 (vers 6 November 2007), see www.w3.org"> 
<title></title> 
</head> 
<body> 
<p>This is some text with a <a href="http://www.example.com/" 
title="Example link">bit</a></p> 
</body> 
</html> 

Надеется, что это помогает

Edit: Лучше regex

`p = re.compile(r'<[^<]*?>')` 
Смежные вопросы