2008-08-27 40 views
19

को छोड़कर सभी HTML टैग से मिलान करने के लिए Regex मुझे पर्ल में नियमित अभिव्यक्ति का उपयोग करके सभी टैग मिलान और निकालना होगा। मैं निम्नलिखित है:<p>और</p>

<\\??(?!p).+?> 

लेकिन यह अभी भी बंद करने </p> टैग के साथ मेल खाता है। समापन टैग के साथ मिलान करने के बारे में कोई संकेत भी?

नोट, यह xhtml पर किया जा रहा है।

+3

अपने HTML/Regex विचारों के लिए इस उत्तर को देखें - http://stackoverflow.com/questions/1732348/regex-मैच खुले टैग को छोड़कर-एक्सएचटीएमएल-संयमी-टैग/1732454 # 1 732454 –

उत्तर

9

मैं इस के साथ आया था:

<(?!\/?p(?=>|\s.*>))\/?.*?> 

x/ 
<   # Match open angle bracket 
(?!   # Negative lookahead (Not matching and not consuming) 
    \/?  # 0 or 1/
    p   # p 
    (?=  # Positive lookahead (Matching and not consuming) 
    >  # > - No attributes 
     |  # or 
    \s  # whitespace 
    .*  # anything up to 
    >  # close angle brackets - with attributes 
    )   # close positive lookahead 
)   # close negative lookahead 
      # if we have got this far then we don't match 
      # a p tag or closing p tag 
      # with or without attributes 
\/?   # optional close tag symbol (/) 
.*?   # and anything up to 
>   # first closing tag 
/

यह अब के साथ या गुण और समापन पी टैग के बिना पी टैग के साथ सौदा होगा, लेकिन साथ या गुण के बिना पूर्व और इसी तरह के टैग से मेल खाएगी,।

यह गुणों को अलग नहीं करता है, लेकिन मेरा स्रोत डेटा उन्हें अंदर नहीं डालता है। मैं इसे बाद में बदल सकता हूं, लेकिन यह अब के लिए पर्याप्त होगा।

+0

आखिर में कोई भी जो रेगेक्स और प्रत्येक भाग की व्याख्या के बारे में उत्तर पोस्ट करता है। आप महोदय, एक इंटरगैलेक्टिक पुरस्कार के लायक हैं! – SpaceDog

1

यह मानते हुए कि इस PERL में काम करेंगे के रूप में यह भाषाओं का दावा है कि PERL-संगत सिंटैक्स का उपयोग करने में करता है:

/<\/?[^p][^>]*>/

संपादित करें:

लेकिन उस से मेल नहीं खाएगी एक <pre> या <param> टैग, दुर्भाग्य से।

यह, शायद?

/<\/?(?!p>|p)[^>]+>/ 

इसमें <p> टैग शामिल हैं जो विशेषताएँ भी हैं।

0

इस प्रयास करें, यह काम करना चाहिए:

/<\/?([^p](\s.+?)?|..+?)>/ 

स्पष्टीकरण: यह "पी" को छोड़कर या तो एक पत्र, एक वैकल्पिक खाली स्थान के और अधिक अक्षर, या एक से अधिक पत्र (कम से कम दो) के बाद से मेल खाता है।

/संपादित करें: मैंने p टैग में विशेषताओं को संभालने की क्षमता को जोड़ा है।

2

चूंकि HTML नियमित भाषा नहीं है, इसलिए मैं नियमित रूप से अभिव्यक्ति की अपेक्षा नहीं करता कि यह मिलान करने में एक बहुत अच्छी नौकरी करे। वे इस कार्य तक हो सकते हैं (हालांकि मुझे विश्वास नहीं है), लेकिन मैं कहीं और दिखने पर विचार करूंगा; मुझे यकीन है कि एचटीएमएल में हेरफेर करने के लिए पर्ल में कुछ ऑफ-द-शेल्फ पुस्तकालय होना चाहिए।

वैसे भी, मुझे लगता है कि होता है कि क्या आप मिलान कराना चाहते < /?(p.+|.*)(\s*.*) > गैर लालच से (मैं पर्ल के regexp वाक्य रचना की अनियमितता नहीं जानते इसलिए मैं आगे की मदद नहीं कर सकता)। मैं मान रहा हूं कि व्हाइटस्पेस का मतलब है। शायद यह नहीं है। किसी भी तरह से, आप कुछ ऐसा चाहते हैं जो व्हाइट्स स्पेस द्वारा टैग नाम से ऑफ़सेट गुणों से मेल खाएगा। लेकिन इससे कहीं अधिक कठिन है क्योंकि लोग अक्सर स्क्रिप्ट और टिप्पणियों के अंदर अनचाहे कोण ब्रैकेट डालते हैं और शायद उद्धृत विशेषता मान भी उद्धृत करते हैं, जिन्हें आप मैच नहीं करना चाहते हैं।

तो जैसा कि मैंने कहा, मुझे नहीं लगता कि मुझे लगता है कि नौकरी के लिए regexps सही उपकरण नहीं है।

2

एचटीएमएल के बाद से एक नियमित रूप से भाषा

एचटीएमएल नहीं है नहीं है, लेकिन HTML टैग हैं और वे adequatly नियमित अभिव्यक्ति द्वारा वर्णित किया जा सकता है।

-1

आप शायद भी < p> टैग पर कोई गुण निकाल देना चाहिए किसी को बुरा की तरह कुछ कर सकता है के बाद से:

<p onclick="document.location.href='http://www.evil.com'">Clickable text</p> 

यह करने के लिए सबसे आसान तरीका है, उपयोग करने के लिए खोज करने के लिए रेगुलर एक्सप्रेशन से लोगों को यहां का सुझाव है & ltp> विशेषताओं के साथ टैग के लिए, और उन्हें < पी> टैग के साथ गुणों के बिना प्रतिस्थापित करें। सिर्फ सुरक्षित पक्ष पर होने के लिए।

3

यह सुनिश्चित नहीं है कि आप ऐसा क्यों करना चाहते हैं - एचटीएमएल स्वच्छता के लिए रेगेक्स हमेशा सर्वोत्तम तरीका नहीं है (आपको विशेषताओं को स्वच्छ करने और जावास्क्रिप्ट को हटाने के लिए याद रखना होगा: hrefs और पसंद) ... लेकिन,

(<[^pP].*?>|</[^pP]>)

वर्बोस:: रेगुलर एक्सप्रेशन HTML टैग कि नहीं <p></p> हैं मैच के लिए

(
    <    # < opening tag 
     [^pP].*? # p non-p character, then non-greedy anything 
    >    # > closing tag 
|     # ....or.... 
    </    # </ 
     [^pP]  # a non-p tag 
    >    # > 
) 
37

आप एक regex कुछ वीं की तरह उपयोग करते हुए, पर जोर देते हैं ज्यादातर मामलों में काम करेंगे जाता है:

# Remove all HTML except "p" tags 
$html =~ s{<(?>/?)(?:[^pP]|[pP][^\s>/])[^>]*>}{}g; 

स्पष्टीकरण:

s{ 
    <    # opening angled bracket 
    (?>/?)  # ratchet past optional/
    (?: 
    [^pP]  # non-p tag 
    |   # ...or... 
    [pP][^\s>/] # longer tag that begins with p (e.g., <pre>) 
) 
    [^>]*   # everything until closing angled bracket 
    >    # closing angled bracket 
}{}gx; # replace with nothing, globally 

लेकिन वास्तव में, अपने आप को कुछ सिर दर्द बचाने के लिए और के बजाय एक पार्सर का उपयोग करें। सीपीएएन में कई मॉड्यूल हैं जो उपयुक्त हैं। यहाँ HTML::TokeParser मॉड्यूल कि अत्यंत सक्षम HTML::Parser CPAN वितरण के साथ आता है का उपयोग कर एक उदाहरण है:

use strict; 

use HTML::TokeParser; 

my $parser = HTML::TokeParser->new('/some/file.html') 
    or die "Could not open /some/file.html - $!"; 

while(my $t = $parser->get_token) 
{ 
    # Skip start or end tags that are not "p" tags 
    next if(($t->[0] eq 'S' || $t->[0] eq 'E') && lc $t->[1] ne 'p'); 

    # Print everything else normally (see HTML::TokeParser docs for explanation) 
    if($t->[0] eq 'T') 
    { 
    print $t->[1]; 
    } 
    else 
    { 
    print $t->[-1]; 
    } 
} 

HTML::Parser एक फ़ाइल नाम, एक खुली फ़ाइल हैंडल या एक स्ट्रिंग के रूप में इनपुट स्वीकार करता है। उपरोक्त कोड को लाइब्रेरी में लपेटना और गंतव्य कॉन्फ़िगर करने योग्य बनाना (यानी, उपर्युक्त में केवल print आईएनजी नहीं) मुश्किल नहीं है। परिणाम नियमित अभिव्यक्तियों का उपयोग करने की कोशिश करने से अधिक विश्वसनीय, रखरखाव योग्य और संभवतः तेज़ (HTML :: पार्सर सी-आधारित बैकएंड का उपयोग करता है) होगा।

+0

अपने आप को और भी सिरदर्द बचाएं और उत्कृष्ट HTML :: TokeParser :: सरल मॉड्यूल का उपयोग करें। :-) –

1

आप भी पी टैग में "पी" से पहले व्हाइटस्पेस की अनुमति देना चाहेंगे। सुनिश्चित नहीं है कि आप इसमें कितनी बार भाग लेंगे, लेकिन < पी> पूरी तरह से मान्य HTML है।

16

मेरी राय में, HTML पार्सर के अलावा किसी अन्य चीज़ के साथ HTML को पार्स करने का प्रयास करना सिर्फ दर्द की दुनिया के लिए पूछ रहा है। एचटीएमएल वास्तव में जटिल भाषा है (जो एक्सएचटीएमएल बनाया गया था, जो कि HTML से कहीं अधिक सरल है) में से एक है।

उदाहरण के लिए, इस:

<HTML/
    <HEAD/
    <TITLE/>/
    <P/> 

एक पूर्ण, 100% अच्छी तरह से गठित, 100% मान्य HTML दस्तावेज है।(ठीक है, यह doctype घोषणा कि अन्य की तुलना में कमी है, लेकिन ...)

यह अर्थ की दृष्टि से

<html> 
    <head> 
    <title> 
     &gt; 
    </title> 
    </head> 
    <body> 
    <p> 
     &gt; 
    </p> 
    </body> 
</html> 

के बराबर है लेकिन यह फिर भी मान्य HTML है कि आप से निपटने के लिए करने के लिए जा रहे हैं। आप , निश्चित रूप से, इसे पार्स करने के लिए एक रेगेक्स तैयार कर सकते हैं, लेकिन, जैसा कि पहले से ही सुझाव दिया गया है, एक वास्तविक HTML पार्सर का उपयोग करना बहुत आसान है।

+1

वाह। मैंने आपको विश्वास नहीं किया, लेकिन मैंने इसे W3 सत्यापनकर्ता के माध्यम से एक HTML 4.01 सख्त सिद्धांत के साथ चलाया, और यह मान्य करता है। यह चेतावनी फेंकता है, लेकिन वाह। – eyelidlessness

+0

örg, आप ** ** ** सही हैं! हालांकि, अगर बहुत अच्छी तरह से बाधित इनपुट सेट है, तो यह इतना बुरा नहीं है। यादृच्छिक लोगों के साथ, हालांकि, यह एक पार्सिंग कक्षा का उपयोग न करने की मूर्खता होगी। किसी और को कड़ी मेहनत करने दो! – tchrist

1

मूल regex बहुत कम प्रयास के साथ काम करने के लिए किया जा सकता है: कि/

<(?>/?)(?!p).+?> 

समस्या थी? (या \?) ने इसे खो दिया जब यह विफल होने के बाद दावा किया गया। इसके आस-पास एक गैर-बैकट्रैकिंग समूह (?> ...) का उपयोग करना इस बात का ख्याल रखता है कि यह कभी भी मिलान किए गए स्लैश को रिलीज़ नहीं करता है, इसलिए (?! P) दावा हमेशा टैग टेक्स्ट की शुरुआत के लिए लगाया जाता है।

(मैंने कहा कि मैं सहमत हूं कि आमतौर पर रेगेक्स के साथ एचटीएमएल को पार्स करने का तरीका नहीं है)।

3

मैंने ज़ेटियस रेगेक्स का उपयोग किया और यह ठीक काम करता है। कुछ फ्लेक्स जेनरेट किए गए टैग को छोड़कर जो हो सकता है:
अंदर कोई रिक्त स्थान नहीं है। मैंने इसे एक सरल के साथ ठीक करने की कोशिश की?

<(?!\/?p(?=>|\s?.*>))\/?.*?> 

मैं इसे उपयोग कर रहा हूँ टैग स्पष्ट करने के लिए फ्लेक्स एचटीएमएल पाठ उत्पन्न से तो मैं भी अधिक एक्सेप्टेड टैग कहा::\ रों और यह है कि यह काम कर रहा है लग रहा है के बाद

<(?!\/?(p|a|b|i|u|br)(?=>|\s?.*>))\/?.*?> 
1

Xetius, इस प्राचीन प्रश्न को पुनर्जीवित करना क्योंकि इसका एक सरल समाधान था जिसका उल्लेख नहीं किया गया था। (regex bounty quest के लिए कुछ शोध करते समय अपना प्रश्न मिला।)

एचटीएमएल को पार्स करने के लिए रेगेक्स का उपयोग करने के बारे में सभी अस्वीकरण के साथ, यह करने का एक आसान तरीका है।

#!/usr/bin/perl 
$regex = '(<\/?p[^>]*>)|<[^>]*>'; 
$subject = 'Bad html <a> </I> <p>My paragraph</p> <i>Italics</i> <p class="blue">second</p>'; 
($replaced = $subject) =~ s/$regex/$1/eg; 
print $replaced . "\n"; 

इस live demo

संदर्भ देखें

How to match pattern except in situations s1, s2, s3

How to match a pattern unless...

संबंधित मुद्दे