2010-04-06 16 views
8

मुझे निम्न कार्यक्षमता चाहिए।स्ट्रिप टैग पायथन

input : this is test <b> bold text </b> normal text 
expected output: this is test normal text 

अर्थात निर्दिष्ट टैग

+0

आप किसी भी टैग या सिर्फ उदाहरण दिया के लिए इस की ज़रूरत है ? –

+1

@ cb160 मुझे किसी भी टैग के साथ चाहिए। i.e जेनेरिक – developer

+0

क्या आप चाहते हैं कि यह सभी टैग या केवल आपके द्वारा सूचीबद्ध की गई पट्टी को पट्टी करें? –

उत्तर

9

समाधान BeautifulSoup का उपयोग कर:

from BeautifulSoup import BeautifulSoup 
def removeTag(soup, tagname): 
    for tag in soup.findAll(tagname): 
     contents = tag.contents 
     parent = tag.parent 
     tag.extract() 

s = BeautifulSoup("abcd <b> btag </b> hello <d>dtag</d>") 

removeTag(s,"b") 
print s 
removeTag(s, "d") 
print s 

रिटर्न:

>>> 
abcd hello <d>dtag</d> 
abcd hello 
5

की सामग्री को हटा BeautifulSoup के साथ:

from BeautifulSoup import BeautifulSoup  
''.join(BeautifulSoup(page).findAll(text=True)) 

http://www.ghastlyfop.com/blog/2008/12/strip-html-tags-from-string-python.html

+1

+1 एचटीएमएल –

+0

@ आरईआर पर आरईएस का उपयोग नहीं करने के लिए मैंने पहले ही यह कोशिश की है। लेकिन यह उस टैग को हटा दें जिसमें सामग्री नहीं है। – developer

+0

@ user283405। हम्म, सुनिश्चित करें कि आप उचित शब्द का प्रयोग करें। मुझे लगता है कि आपको एक तत्व की सामग्री को हटाने के लिए क्या चाहिए (मूल रूप से कुछ टैग खोलने से शुरू होता है और समापन टैग के साथ समाप्त होता है)। सही? –

2

पर मिले के साथ प्रयास करें:

import re 
input = 'this is test <b> bold text </b> normal text' 
output = re.compile(r'<[^<]*?/?>').sub('', input) 
print output 
+2

रेगेक्स + एचटीएमएल = गलत। अनिवार्य रूप से एचटीएमएल, क्योंकि यह (ज्यादातर) घोंसला है, नियमित भाषा नहीं है, इसलिए नियमित अभिव्यक्तियों द्वारा सही ढंग से पार्स नहीं किया जा सकता है। यह सोलोर है: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags –

+0

आप निश्चित रूप से सही हैं; वैसे भी यह ओपी उदाहरण के लिए काम किया;)। – systempuntoout

+1

जहां तक ​​इस सवाल का सवाल है, हम HTML को पार्स नहीं कर रहे हैं (यानी हमें परवाह नहीं है कि पाठ के कौन से हिस्से 'खुले' और 'करीबी' टैग के बीच हैं) और हमें परवाह नहीं है कि कितनी गहराई से घोंसला टैग हैं, इसलिए regex उपयोग करने के लिए एक बिल्कुल सही उपकरण है। (हालांकि यह अन्य उत्तरों में उल्लिखित टैगों के अलावा '<' वर्णों के कारण गिरता है) –

3

यदि आपके पास पायथन को ध्यान में रखें (हालांकि regexps काफी सामान्य हैं), आप Django's strip_tags filter से कुछ प्रेरणा ले सकते हैं।

यहाँ संपूर्णता के लिए पुन: निर्मित -

def strip_tags(value): 
    """Returns the given HTML with all tags stripped.""" 
    return re.sub(r'<[^>]*?>', '', force_unicode(value)) 

संपादित करें: यदि आप इस का उपयोग कर रहे, या किसी अन्य regexp समाधान, कृपया ध्यान रखें कि इसे ध्यान से तैयार एचटीएमएल के माध्यम से की सुविधा देता है, तो (टिप्पणी देखें) के साथ-साथ एचटीएमएल टिप्पणियां और इसलिए अविश्वसनीय इनपुट के साथ उपयोग नहीं किया जाना चाहिए। इसके बजाय अविश्वसनीय इनपुट के लिए कुछ सुंदरसूप, एचटीएमएल 5 एलआईबी या एलएक्सएमएल उत्तरों का उपयोग करने पर विचार करें।

+0

Django के 'strip_tags' फ़िल्टर टूटा हुआ है और बेकार है। विशेषता मानों में '>' वर्ण डालने के लिए यह पूरी तरह से मान्य है, और यह टिप्पणियों जैसे अन्य मार्कअप संरचनाओं को संभालने का भी प्रयास नहीं करता है। – bobince

+0

सहमत (मैंने स्टैक ओवरव्लो पर कहीं पागल सवाल पढ़ा है HTML को पार्स करने के लिए regexp तैयार करने की कोशिश कर रहा है :)। व्यक्तिगत रूप से मेरी वेबसाइट पर, मैं एक ही चीज करने के लिए lxml का उपयोग करता हूं (साथ ही निषिद्ध टैग और विशेषताओं को अलग करना)। मुझे लगता है कि उपर्युक्त उत्तर में अभी भी कुछ वैध उपयोग है जब प्रदर्शन महत्वपूर्ण है, लेकिन केवल उन गंभीर सीमाओं के साथ लागू किया जाना चाहिए। – Sam

2

ऐसा लगता है कि आप HTMLParser चाहते हैं। (html.parser पायथन 3. में)

from HTMLParser import HTMLParser 
from sys import stdout 
class Filter(HTMLParser): 
    def __init__(self, ignored_tags): 
     super(Filter, self).__init__() 
     self.ignorelevel = 0 
     self. ignored_tags = ignored_tags 
    def handle_starttag(self, tag, attrs): 
     if self.ignorelevel > 0: 
      self.ignorelevel += 1 
     elif tag in self.ignored_tags: 
      self.ignorelevel = 1 
     else: 
      # One of these two. Test and see. 
      stdout.write(self.get_starttag_text()) 
      #stdout.write('<' + self.get_starttag_text() + '>') 
    def handle_startendtag(self, tag, attrs): 
     if self.ignorelevel == 0 and tag not in self.ignored_tags: 
      # One of these two. Test and see. 
      stdout.write(self.get_starttag_text()) 
      #stdout.write('<' + self.get_starttag_text() + '/>') 
    def handle_endtag(self, tag): 
     if self.ignorelevel > 0: 
      self.ignorelevel -= 1 
      if self.ignorelevel > 0: 
       return 
     stdout.write('</' + tag + '>') 
    def handle_data(self, data): 
     stdout.write(data) 
    def handle_charref(self, name): 
     stdout.write('&#' + name + ';') 
    def handle_entityref(self, name): 
     stdout.write('&' + name + ';') 
    def handle_comment(self, data): 
     stdout.write('<!-- ' + data + ' -->') 
    def handle_decl(self, data): 
     stdout.write('<!' + data + '>') 
    def handle_pi(self, data): 
     stdout.write('<?' + data + '>') 
0

मैं http://code.google.com/p/html5lib/ का प्रयोग करेंगे अगर आप कुछ सुरक्षित टैग शामिल करना चाहते हैं।

http://code.google.com/p/html5lib/wiki/UserDocumentation पर "Sanitizing Tokenizer" अनुभाग देखें।

भेद्यता के लिए परीक्षण करना याद रखें यदि यह एक महत्वपूर्ण सेवा है: http://ha.ckers.org/xss.html

0

सैम जवाब क्या काफी अच्छी तरह से जहाँ तक मैं बता सकता है चाहता था, लेकिन यह सुनिश्चित करें कि किसी भी बचे बनाने के लिए भुगतान कर सकते हैं करना चाहिए < > वर्ण & लेफ्टिनेंट के साथ प्रतिस्थापित किए गए हैं; और & gt; दुरुपयोग/अवैध HTML को रोकने के लिए क्रमशः।

इस दृष्टिकोण का लाभ यह है कि यह अविश्वसनीय रूप से विकृत HTML संदर्भ/टैग स्वीकार कर सकता है। सुंदर सूप भी विकृत टैग को काफी अच्छी तरह से संभालता है लेकिन html5lib, sgmllib और htmllib अमान्य कोड पर चकित कर सकता है, अगर मुझे सही याद है तो कुछ और से अधिक। तो यह काफी अच्छी तरह से परीक्षण किया है

import re 
from htmlentitydefs import name2codepoint, codepoint2name 

S = '1234567890ABCDEF' 
DHex = {} 
for i in S: 
    DHex[i.lower()] = None 
    DHex[i.upper()] = None 

def IsHex(S): 
    if not S: return False 
    for i in S: 
     if i not in DHex: 
      return False 
    return True 

def UnEscape(S, LReEscape=None): 
    # Converts HTML character references into a unicode string to allow manipulation 
    # 
    # If LUnEscape is provided, then the positions of the escaped characters will be 
    # added to allow turning the result back into HTML with ReEscape below, validating 
    # the references and escaping all the rest 
    # 
    # This is needed to prevent browsers from stripping out e.g. &#32; (spaces) etc 
    re = LReEscape != None 

    LRtn = [] 
    L = S.split('&') 
    xx = 0 
    yy = 0 
    for iS in L: 
     if xx: 
      LSplit = iS.split(';') 
      if LSplit[0].lower() in name2codepoint: 
       # A character reference, e.g. '&amp;' 
       a = unichr(name2codepoint[LSplit[0].lower()]) 
       LRtn.append(a+';'.join(LSplit[1:])) 
       if re: LReEscape.append((yy, a)) 

      elif LSplit[0] and LSplit[0][0] == '#' and LSplit[0][1:].isdigit(): 
       # A character number e.g. '&#52;' 
       a = unichr(int(LSplit[0][1:])) 
       LRtn.append(a+';'.join(LSplit[1:])) 
       if re: LReEscape.append((yy, a)) 

      elif LSplit[0] and LSplit[0][0] == '#' and LSplit[0][1:2].lower() == 'x' and IsHex(LSplit[0][2:]): 
       # A hexadecimal encoded character 
       a = unichr(int(LSplit[0][2:].lower(), 16)) # Hex -> base 16 
       LRtn.append(a+';'.join(LSplit[1:])) 
       if re: LReEscape.append((yy, a)) 

      else: LRtn.append('&%s' % ';'.join(LSplit)) 
     else: LRtn.append(iS) 
     xx += 1 
     yy += len(LRtn[-1]) 
    return ''.join(LRtn) 

def ReEscape(LReEscape, S, EscFn): 
    # Re-escapes the output of UnEscape to HTML, ensuring e.g. &#32; 
    # is turned back again and isn't stripped at a browser level 
    L = [] 
    prev = 0 
    for x, c in LReEscape: 
     if x != prev: 
      L.append(EscFn(S[prev:x])) 

     o = ord(c) 
     if o in codepoint2name: 
      L.append('&%s;' % codepoint2name[o]) 
     else: L.append('&#%s;' % o) 
     prev = x+len(c) 
    L.append(EscFn(S[prev:])) 
    return ''.join(L) 

def escape(value): 
    # Escape left over <>& tags 
    value = value.replace('&', '&amp;') 
    value = value.replace('>', '&gt;') 
    value = value.replace('<', '&lt;') 
    return value 

def strip_tags(value): 
    # Strip HTML tags 
    value = re.sub(r'<[^>]*?>', '', value) 
    print 'No Tags:', value 

    # Validate & references 
    LReEscape = [] 
    value = UnEscape(value, LReEscape) 
    value = ReEscape(LReEscape, value, EscFn=escape) 
    print 'References Validated:', value 
    return value 

if __name__ == '__main__': 
    # Outputs: 
    # No Tags: this is test bold text normal text >< &blah &amp; &amp 
    # References Validated: this is test bold text normal text &gt;&lt; &amp;blah &amp; &amp; 
    strip_tags('this is test <b> bold text </b> normal text >< &blah &amp; &amp') 
0

यह काम कर रहा है कोड अपने प्रोजेक्ट Supybot से लिया,:

निम्नलिखित कोड भी & एचटीएमएल संदर्भ सत्यापित करता

class HtmlToText(sgmllib.SGMLParser): 
    """Taken from some eff-bot code on c.l.p.""" 
    entitydefs = htmlentitydefs.entitydefs.copy() 
    entitydefs['nbsp'] = ' ' 
    def __init__(self, tagReplace=' '): 
     self.data = [] 
     self.tagReplace = tagReplace 
     sgmllib.SGMLParser.__init__(self) 

    def unknown_starttag(self, tag, attr): 
     self.data.append(self.tagReplace) 

    def unknown_endtag(self, tag): 
     self.data.append(self.tagReplace) 

    def handle_data(self, data): 
     self.data.append(data) 

    def getText(self): 
     text = ''.join(self.data).strip() 
     return normalizeWhitespace(text) 

def htmlToText(s, tagReplace=' '): 
    """Turns HTML into text. tagReplace is a string to replace HTML tags with. 
    """ 
    x = HtmlToText(tagReplace) 
    x.feed(s) 
    return x.getText()

docstring नोटों के रूप में, यह जन्म फ्रेड्रिक लुंड के साथ, मुझे नहीं।वे कहते हैं कि के रूप में, महान लेखकों चोरी :)

0

webob.exc मॉड्यूल का उपयोग करें:

from webob.exc import strip_tags 

और फिर इसका इस्तेमाल:

print strip_tags('a<br/>b') 
>> ab 
संबंधित मुद्दे