क्या करने के लिए नियमित अभिव्यक्ति पैटर्न स्ट्रिंग में कहीं भी मेल नहीं खाता है?


181

मैं <input>इस पैटर्न का उपयोग करते हुए "छिपे हुए" फ़ील्ड से मिलान करने का प्रयास कर रहा हूं :

/<input type="hidden" name="([^"]*?)" value="([^"]*?)" />/

यह नमूना प्रपत्र डेटा है:

<input type="hidden" name="SaveRequired" value="False" /><input type="hidden" name="__VIEWSTATE1" value="1H4sIAAtzrkX7QfL5VEGj6nGi+nP" /><input type="hidden" name="__VIEWSTATE2" value="0351118MK" /><input type="hidden" name="__VIEWSTATE3" value="ZVVV91yjY" /><input type="hidden" name="__VIEWSTATE0" value="3" /><input type="hidden" name="__VIEWSTATE" value="" /><input type="hidden" name="__VIEWSTATE" value="" />

लेकिन मुझे यकीन है कि नहीं कर रहा हूँ type, nameऔर valueगुण हमेशा एक ही क्रम में दिखाई देगा। यदि typeविशेषता अंतिम है, तो मैच विफल हो जाएगा क्योंकि मेरे पैटर्न में यह शुरू में है।

प्रश्न:
मैं अपने पैटर्न को कैसे बदल सकता हूं ताकि यह <input>टैग की विशेषताओं की परवाह किए बिना मेल खाएगा ?

पुनश्च: जिस तरह से मैं नियमित भावों के परीक्षण के लिए एडोब एयर आधारित RegEx डेस्कटॉप टूल का उपयोग कर रहा हूं ।


4
रेगेक्स उत्कृष्ट समाधान है यदि आपके पास उत्पन्न html पर नियंत्रण है क्योंकि यह नियमित बनाम नियमित बहस नहीं है, लेकिन मुझे मेरा मामला पता नहीं है कि कैसे एचटीएमएल भविष्य में बदलने जा रहा है इसलिए सबसे अच्छी बात यह है कि रेगेक्स के बजाय पार्सर का उपयोग करें, मैंने उपयोग किया है मेरे प्रोजेक्ट में regex उन हिस्सों में है जिन पर मेरा नियंत्रण है
सलमान

जवाबों:


108

यहां सभी उत्तरों के विपरीत, आप जो रेगेक्स करने की कोशिश कर रहे हैं, वह पूरी तरह से वैध समाधान है। ऐसा इसलिए है क्योंकि आप संतुलित टैग से मिलान करने की कोशिश नहीं कर रहे हैं - यह regex के साथ असंभव होगा! लेकिन आप केवल एक टैग में क्या मिलान कर रहे हैं, और यह पूरी तरह से नियमित है।

यहाँ समस्या है, यद्यपि। आप इसे केवल एक रेगेक्स के साथ नहीं कर सकते ... आपको एक <input>टैग पर कब्जा करने के लिए एक मैच करने की आवश्यकता है , फिर उस पर आगे की प्रक्रिया करें। ध्यान दें कि यह केवल तभी काम करेगा जब उनमें से कोई भी गुण मान >न हों, इसलिए यह सही नहीं है, लेकिन इसे सेंस इनपुट के लिए पर्याप्त होना चाहिए।

यहाँ कुछ पर्ल (छद्म) कोड है जो आपको दिखाता है कि मेरा क्या मतलब है:

my $html = readLargeInputFile();

my @input_tags = $html =~ m/
    (
        <input                      # Starts with "<input"
        (?=[^>]*?type="hidden")     # Use lookahead to make sure that type="hidden"
        [^>]+                       # Grab the rest of the tag...
        \/>                         # ...except for the />, which is grabbed here
    )/xgm;

# Now each member of @input_tags is something like <input type="hidden" name="SaveRequired" value="False" />

foreach my $input_tag (@input_tags)
{
  my $hash_ref = {};
  # Now extract each of the fields one at a time.

  ($hash_ref->{"name"}) = $input_tag =~ /name="([^"]*)"/;
  ($hash_ref->{"value"}) = $input_tag =~ /value="([^"]*)"/;

  # Put $hash_ref in a list or something, or otherwise process it
}

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

संपादित करें: हालांकि, मैं इस बात से सहमत हूँ कि सामान्य तौर पर, HTML पार्सर का उपयोग करना शायद आसान और बेहतर होता है और आपको वास्तव में अपने कोड को फिर से डिज़ाइन करने या अपने उद्देश्यों की पुन: जांच करने पर विचार करना चाहिए। :-) लेकिन मुझे इस जवाब को घुटने के बल चलने वाली प्रतिक्रिया के काउंटर के रूप में पोस्ट करना था कि HTML के किसी भी सबसेट को पार्स करना असंभव है: जब आप संपूर्ण विनिर्देश पर विचार करते हैं, तो HTML और XML दोनों अनियमित होते हैं, लेकिन एक टैग का विनिर्देश शालीनता से नियमित है , निश्चित रूप से पीसीआरई की शक्ति के भीतर।


14
यहां सभी उत्तरों के विपरीत नहीं । :)
tchrist

6
@tchrist: जब मैंने मेरा पोस्ट किया तो आपका जवाब यहाँ नहीं था। ;-)
प्लैटिनम एज़्योर

7
हाँ अच्छी तरह से - किसी कारण के लिए मुझे तुम्हारी तुलना में टाइप करने में अधिक समय लगा। मुझे लगता है कि मेरे कीबोर्ड को ग्रॉसिंग की आवश्यकता होगी। :)
21

6
यह अमान्य HTML है - इसका मूल्य होना चाहिए = "& lt; क्या आप वाकई इस बारे में निश्चित हैं? & Gt;" यदि वह जिस जगह पर काम कर रहा है, वह इस तरह की चीजों से बचने के लिए एक खराब काम करता है, तो उसे एक अधिक परिष्कृत समाधान की आवश्यकता होगी - लेकिन अगर वे इसे सही करते हैं (और यदि उसका इस पर नियंत्रण है, तो उसे यह सुनिश्चित करना चाहिए कि यह सही है) तो वह ठीक है।
रॉस स्नाइडर

14
विषय पर सबसे अच्छा एसओ उत्तर के लिए अनिवार्य लिंक (संभवतः सबसे अच्छा एसओ उत्तर अवधि): stackoverflow.com/questions/1732348/…
डैनियल रिबेरो

682

अरे हाँ आप HTML को पार्स करने के लिए Regexes का उपयोग कर सकते हैं !

जिस कार्य के लिए आप प्रयास कर रहे हैं, उसके लिए रेग्जेस पूरी तरह से ठीक हैं!

यह है सच है कि ज्यादातर लोगों को नियमित अभिव्यक्ति के साथ पार्स एचटीएमएल की कठिनाई बहुत मूल्यवान समझना और इसलिए इतनी खराब है।

लेकिन यह कम्प्यूटेशनल सिद्धांत से संबंधित कुछ मूलभूत दोष नहीं है। उस नीचता को इधर-उधर तोता है , लेकिन क्या आप उन पर विश्वास नहीं करते हैं।

तो जबकि यह निश्चित रूप से किया जा सकता है (यह पोस्टिंग इस असंगत तथ्य के अस्तित्व प्रमाण के रूप में कार्य करता है), इसका मतलब यह नहीं है कि यह  होना  चाहिए।

आपको अपने लिए यह तय करना होगा कि क्या आप यह लिखने के काम पर हैं कि किस राशि को समर्पित, विशेष उद्देश्य वाले HTML पार्सर को regexes से बाहर करना है। ज्यादातर लोग नहीं हैं।

लेकिन मैं हूं। ☻


जनरल रेगेक्स-आधारित HTML पार्सिंग सॉल्यूशंस

पहले मैं दिखाऊंगा कि रीगेक्स के साथ मनमाना HTML पार्स करना कितना आसान है । इस पोस्टिंग के अंत में पूरा कार्यक्रम, लेकिन पार्सर का दिल है:

for (;;) {
  given ($html) {
    last                    when (pos || 0) >= length;
    printf "\@%d=",              (pos || 0);
    print  "doctype "   when / \G (?&doctype)  $RX_SUBS  /xgc;
    print  "cdata "     when / \G (?&cdata)    $RX_SUBS  /xgc;
    print  "xml "       when / \G (?&xml)      $RX_SUBS  /xgc;
    print  "xhook "     when / \G (?&xhook)    $RX_SUBS  /xgc;
    print  "script "    when / \G (?&script)   $RX_SUBS  /xgc;
    print  "style "     when / \G (?&style)    $RX_SUBS  /xgc;
    print  "comment "   when / \G (?&comment)  $RX_SUBS  /xgc;
    print  "tag "       when / \G (?&tag)      $RX_SUBS  /xgc;
    print  "untag "     when / \G (?&untag)    $RX_SUBS  /xgc;
    print  "nasty "     when / \G (?&nasty)    $RX_SUBS  /xgc;
    print  "text "      when / \G (?&nontag)   $RX_SUBS  /xgc;
    default {
      die "UNCLASSIFIED: " .
        substr($_, pos || 0, (length > 65) ? 65 : length);
    }
  }
}

देखें कि पढ़ना कितना आसान है?

जैसा कि लिखा गया है, यह HTML के प्रत्येक टुकड़े की पहचान करता है और बताता है कि उस टुकड़े को कहां पाया गया। आप इसे आसानी से संशोधित कर सकते हैं, जो आप किसी भी प्रकार के टुकड़े के साथ चाहते हैं, या इन से अधिक विशेष प्रकार के लिए कर सकते हैं।

मेरे पास कोई असफल परीक्षण मामले नहीं हैं (बाएं :): मैंने इस कोड को 100,000 से अधिक HTML फ़ाइलों पर सफलतापूर्वक चलाया है - हर एक जिसे मैं जल्दी और आसानी से अपने हाथों पर प्राप्त कर सकता हूं। उन के अलावा, मैंने इसे विशेष रूप से भोले परासरों को तोड़ने के लिए बनाई गई फाइलों पर भी चलाया है ।

यह कोई भोले तोता नहीं है।

ओह, मुझे यकीन है कि यह सही नहीं है, लेकिन मैं अभी तक इसे तोड़ने में कामयाब नहीं हुआ हूं। मुझे लगता है कि अगर कुछ किया भी, तो प्रोग्राम की स्पष्ट संरचना के कारण फिक्स करना आसान होगा। यहां तक ​​कि रेगेक्स-भारी कार्यक्रमों में भी स्थिरता होनी चाहिए।

अब जब कि रास्ते से बाहर हो गया है, तो मुझे ओपी के प्रश्न को संबोधित करने दें।

ओपी के टास्क को सॉल्व करने के लिए सॉल्व करने का डेमो

html_input_rxनीचे दिया गया छोटा सा प्रोग्राम मैं निम्न आउटपुट का उत्पादन करता हूं, ताकि आप देख सकें कि regexes के साथ HTML पार्स करना ठीक काम करता है जो आप करना चाहते हैं:

% html_input_rx Amazon.com-_Online_Shopping_for_Electronics,_Apparel,_Computers,_Books,_DVDs_\&_more.htm 
input tag #1 at character 9955:
       class => "searchSelect"
          id => "twotabsearchtextbox"
        name => "field-keywords"
        size => "50"
       style => "width:100%; background-color: #FFF;"
       title => "Search for"
        type => "text"
       value => ""

input tag #2 at character 10335:
         alt => "Go"
         src => "http://g-ecx.images-amazon.com/images/G/01/x-locale/common/transparent-pixel._V192234675_.gif"
        type => "image"

पार्स इनपुट टैग, नो ईविल इनपुट देखें

यहां प्रोग्राम के लिए स्रोत है जो ऊपर आउटपुट का उत्पादन करता है।

#!/usr/bin/env perl
#
# html_input_rx - pull out all <input> tags from (X)HTML src
#                  via simple regex processing
#
# Tom Christiansen <tchrist@perl.com>
# Sat Nov 20 10:17:31 MST 2010
#
################################################################

use 5.012;

use strict;
use autodie;
use warnings FATAL => "all";    
use subs qw{
    see_no_evil
    parse_input_tags
    input descape dequote
    load_patterns
};    
use open        ":std",
          IN => ":bytes",
         OUT => ":utf8";    
use Encode qw< encode decode >;

    ###########################################################

                        parse_input_tags 
                           see_no_evil 
                              input  

    ###########################################################

until eof(); sub parse_input_tags {
    my $_ = shift();
    our($Input_Tag_Rx, $Pull_Attr_Rx);
    my $count = 0;
    while (/$Input_Tag_Rx/pig) {
        my $input_tag = $+{TAG};
        my $place     = pos() - length ${^MATCH};
        printf "input tag #%d at character %d:\n", ++$count, $place;
        my %attr = ();
        while ($input_tag =~ /$Pull_Attr_Rx/g) {
            my ($name, $value) = @+{ qw< NAME VALUE > };
            $value = dequote($value);
            if (exists $attr{$name}) {
                printf "Discarding dup attr value '%s' on %s attr\n",
                    $attr{$name} // "<undef>", $name;
            } 
            $attr{$name} = $value;
        } 
        for my $name (sort keys %attr) {
            printf "  %10s => ", $name;
            my $value = descape $attr{$name};
            my  @Q; given ($value) {
                @Q = qw[  " "  ]  when !/'/ && !/"/;
                @Q = qw[  " "  ]  when  /'/ && !/"/;
                @Q = qw[  ' '  ]  when !/'/ &&  /"/;
                @Q = qw[ q( )  ]  when  /'/ &&  /"/;
                default { die "NOTREACHED" }
            } 
            say $Q[0], $value, $Q[1];
        } 
        print "\n";
    } 

}

sub dequote {
    my $_ = $_[0];
    s{
        (?<quote>   ["']      )
        (?<BODY>    
          (?s: (?! \k<quote> ) . ) * 
        )
        \k<quote> 
    }{$+{BODY}}six;
    return $_;
} 

sub descape {
    my $string = $_[0];
    for my $_ ($string) {
        s{
            (?<! % )
            % ( \p{Hex_Digit} {2} )
        }{
            chr hex $1;
        }gsex;
        s{
            & \043 
            ( [0-9]+ )
            (?: ; 
              | (?= [^0-9] )
            )
        }{
            chr     $1;
        }gsex;
        s{
            & \043 x
            ( \p{ASCII_HexDigit} + )
            (?: ; 
              | (?= \P{ASCII_HexDigit} )
            )
        }{
            chr hex $1;
        }gsex;

    }
    return $string;
} 

sub input { 
    our ($RX_SUBS, $Meta_Tag_Rx);
    my $_ = do { local $/; <> };  
    my $encoding = "iso-8859-1";  # web default; wish we had the HTTP headers :(
    while (/$Meta_Tag_Rx/gi) {
        my $meta = $+{META};
        next unless $meta =~ m{             $RX_SUBS
            (?= http-equiv ) 
            (?&name) 
            (?&equals) 
            (?= (?&quote)? content-type )
            (?&value)    
        }six;
        next unless $meta =~ m{             $RX_SUBS
            (?= content ) (?&name) 
                          (?&equals) 
            (?<CONTENT>   (?&value)    )
        }six;
        next unless $+{CONTENT} =~ m{       $RX_SUBS
            (?= charset ) (?&name) 
                          (?&equals) 
            (?<CHARSET>   (?&value)    )
        }six;
        if (lc $encoding ne lc $+{CHARSET}) {
            say "[RESETTING ENCODING $encoding => $+{CHARSET}]";
            $encoding = $+{CHARSET};
        }
    } 
    return decode($encoding, $_);
}

sub see_no_evil {
    my $_ = shift();

    s{ <!    DOCTYPE  .*?         > }{}sx; 
    s{ <! \[ CDATA \[ .*?    \]\] > }{}gsx; 

    s{ <script> .*?  </script> }{}gsix; 
    s{ <!--     .*?        --> }{}gsx;

    return $_;
}

sub load_patterns { 

    our $RX_SUBS = qr{ (?(DEFINE)
        (?<nv_pair>         (?&name) (?&equals) (?&value)         ) 
        (?<name>            \b (?=  \pL ) [\w\-] + (?<= \pL ) \b  )
        (?<equals>          (?&might_white)  = (?&might_white)    )
        (?<value>           (?&quoted_value) | (?&unquoted_value) )
        (?<unwhite_chunk>   (?: (?! > ) \S ) +                    )
        (?<unquoted_value>  [\w\-] *                              )
        (?<might_white>     \s *                                  )
        (?<quoted_value>
            (?<quote>   ["']      )
            (?: (?! \k<quote> ) . ) *
            \k<quote> 
        )
        (?<start_tag>  < (?&might_white) )
        (?<end_tag>          
            (?&might_white)
            (?: (?&html_end_tag) 
              | (?&xhtml_end_tag) 
             )
        )
        (?<html_end_tag>       >  )
        (?<xhtml_end_tag>    / >  )
    ) }six; 

    our $Meta_Tag_Rx = qr{                          $RX_SUBS 
        (?<META> 
            (?&start_tag) meta \b
            (?:
                (?&might_white) (?&nv_pair) 
            ) +
            (?&end_tag)
        )
    }six;

    our $Pull_Attr_Rx = qr{                         $RX_SUBS
        (?<NAME>  (?&name)      )
                  (?&equals) 
        (?<VALUE> (?&value)     )
    }six;

    our $Input_Tag_Rx = qr{                         $RX_SUBS 

        (?<TAG> (?&input_tag) )

        (?(DEFINE)

            (?<input_tag>
                (?&start_tag)
                input
                (?&might_white) 
                (?&attributes) 
                (?&might_white) 
                (?&end_tag)
            )

            (?<attributes>
                (?: 
                    (?&might_white) 
                    (?&one_attribute) 
                ) *
            )

            (?<one_attribute>
                \b
                (?&legal_attribute)
                (?&might_white) = (?&might_white) 
                (?:
                    (?&quoted_value)
                  | (?&unquoted_value)
                )
            )

            (?<legal_attribute> 
                (?: (?&optional_attribute)
                  | (?&standard_attribute)
                  | (?&event_attribute)
            # for LEGAL parse only, comment out next line 
                  | (?&illegal_attribute)
                )
            )

            (?<illegal_attribute>  (?&name) )

            (?<required_attribute> (?#no required attributes) )

            (?<optional_attribute>
                (?&permitted_attribute)
              | (?&deprecated_attribute)
            )

            # NB: The white space in string literals 
            #     below DOES NOT COUNT!   It's just 
            #     there for legibility.

            (?<permitted_attribute>
                  accept
                | alt
                | bottom
                | check box
                | checked
                | disabled
                | file
                | hidden
                | image
                | max length
                | middle
                | name
                | password
                | radio
                | read only
                | reset
                | right
                | size
                | src
                | submit
                | text
                | top
                | type
                | value
            )

            (?<deprecated_attribute>
                  align
            )

            (?<standard_attribute>
                  access key
                | class
                | dir
                | ltr
                | id
                | lang
                | style
                | tab index
                | title
                | xml:lang
            )

            (?<event_attribute>
                  on blur
                | on change
                | on click
                | on dbl   click
                | on focus
                | on mouse down
                | on mouse move
                | on mouse out
                | on mouse over
                | on mouse up
                | on key   down
                | on key   press
                | on key   up
                | on select
            )
        )
    }six;

}

UNITCHECK {
    load_patterns();
} 

END {
    close(STDOUT) 
        || die "can't close stdout: $!";
} 

तुम वहाँ जाओ! इसको कुछ नहीं! :)

केवल आप ही अंदाजा लगा सकते हैं कि रिजेक्स के साथ आपका कौशल किसी विशेष पार्सिंग कार्य पर निर्भर है। हर किसी के कौशल का स्तर अलग है, और हर नया कार्य अलग है। उन नौकरियों के लिए जहां आपके पास एक अच्छी तरह से परिभाषित इनपुट सेट है, regexes स्पष्ट रूप से सही विकल्प है, क्योंकि इससे निपटने के लिए आपके पास HTML का प्रतिबंधित सबसेट होने पर कुछ एक साथ रखना तुच्छ है। यहां तक ​​कि रेगेक्स शुरुआती को रेगेक्स के साथ उन नौकरियों को संभालना चाहिए। और कुछ भी overkill है।

हालाँकि , एक बार जब HTML कम से कम बंद होना शुरू हो जाता है, तो एक बार यह उन तरीकों से प्रभावी होने लगता है, जो आप भविष्यवाणी नहीं कर सकते हैं, लेकिन जो पूरी तरह से कानूनी हैं, एक बार जब आपको विभिन्न प्रकार की चीजों या अधिक जटिल निर्भरता के साथ मिलान करना होगा, तो आप अंततः एक बिंदु पर पहुंच जाएंगे। आपको उस समाधान को प्रभावित करने के लिए अधिक परिश्रम करना पड़ता है जो कि रेक्सक्स का उपयोग करता है, जबकि आपको एक पार्सिंग क्लास का उपयोग करना होगा। जहां ब्रेक-इवन पॉइंट फॉल्स फिर से रेगेक्स के साथ अपने आराम के स्तर पर निर्भर करता है।

तो मुझे क्या करना चाहिए?

मैं आपको यह नहीं बताने जा रहा हूं कि आपको क्या करना चाहिए या क्या नहीं करना चाहिए। मुझे लगता है कि यह गलत है। मैं आपको बस कब्जे के साथ पेश करना चाहता हूं, अपनी आंखें थोड़ी खोलें। आपको यह चुनना है कि आप क्या करना चाहते हैं और आप इसे कैसे करना चाहते हैं। कोई निरपेक्षता नहीं हैं - और कोई भी आपकी खुद की स्थिति के साथ-साथ खुद को भी नहीं जानता है। अगर कुछ ऐसा लगता है कि यह बहुत ज्यादा काम है, ठीक है, शायद यह है। प्रोग्रामिंग मजेदार होनी चाहिए , आप जानते हैं। यदि ऐसा नहीं है, तो आप इसे गलत कर सकते हैं।

html_input_rxकोई भी किसी भी मान्य तरीके से मेरे कार्यक्रम को देख सकता है। ऐसा ही एक है कि आप वास्तव में नियमित अभिव्यक्ति के साथ HTML को पार्स कर सकते हैं । लेकिन एक और यह है कि यह बहुत अधिक है, बहुत कठिन है, लगभग किसी की तुलना में यह कभी भी सोचता है कि यह है। इससे आसानी से निष्कर्ष निकाला जा सकता है कि मेरा कार्यक्रम एक नियम है कि आपको क्या नहीं करना चाहिए , क्योंकि यह वास्तव में बहुत कठिन है।

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

छोटे HTML पार्सिंग समस्याओं के लिए इष्टतम , बड़े वाले के लिए pessimal

यहां तक ​​कि अगर मेरे कार्यक्रम को इस बात के रूप में लिया जाता है कि आपको सामान्य HTML को पार्स करने के लिए रीगेक्स का उपयोग क्यों नहीं करना चाहिए - जो कि ठीक है, क्योंकि मैं थोड़े के लिए इसका मतलब था कि ☺ - यह अभी भी एक आंख खोलने वाला होना चाहिए ताकि अधिक लोग बहुत आम तोड़ सकें और बुरा, अपठनीय, असंरचित और अचूक पैटर्न लिखने की गंदी आदत।

पैटर्न को बदसूरत होना नहीं है, और उन्हें कठिन होना नहीं है। यदि आप बदसूरत पैटर्न बनाते हैं, तो यह आप पर प्रतिबिंब है, न कि उन पर।

पूरी तरह से उत्तम रेगेक्स भाषा

मुझे यह बताने के लिए कहा गया है कि आपकी समस्या का मेरे द्वारा किया गया हल पर्ल में लिखा गया है। क्या आप आश्चर्यचकित हैं? आपने गौर नहीं किया? क्या यह रहस्योद्घाटन बमबारी है?

यह सच है कि अन्य सभी उपकरण और प्रोग्रामिंग भाषाएं पेरिफेन के रूप में रीजेक्स के लिए सुविधाजनक, अभिव्यंजक और शक्तिशाली नहीं हैं। वहाँ एक बड़ा स्पेक्ट्रम है, कुछ दूसरों की तुलना में अधिक उपयुक्त है। सामान्य तौर पर, जिन भाषाओं ने लाइब्रेरी के बजाय कोर भाषा के हिस्से के रूप में रीजेक्स व्यक्त किया है, उनके साथ काम करना आसान है। मैंने पीसीआरई के साथ कुछ भी ऐसा नहीं किया है, जिसमें आप ऐसा नहीं कर सकते, हालांकि, आप प्रोग्राम को अलग तरह से तैयार करेंगे, अगर आप सी के साथ थे।

अंततः अन्य भाषाओं को पकड़ लिया जाएगा जहां पर्ल अब रीगेक्स के संदर्भ में है। मैं यह इसलिए कहता हूं क्योंकि जब पर्ल शुरू हुआ था, तब किसी और के पास पर्ल के रेक्सक्स जैसा कुछ नहीं था। आप जैसा चाहें कुछ भी कहें, लेकिन यह वह जगह है जहां पर्ल ने स्पष्ट रूप से जीत हासिल की: हर किसी ने पर्ल के रेगेक्स को उनके विकास के अलग-अलग चरणों में कॉपी किया। पर्ल ने लगभग (न केवल काफी, बल्कि लगभग) सभी चीजों का बीड़ा उठाया है, जो कि आप आज आधुनिक पैटर्न पर भरोसा करने के लिए आए हैं, चाहे आप किसी भी टूल या भाषा का उपयोग करें। तो अंततः दूसरों को पकड़ लेंगे।

लेकिन वे केवल उसी जगह को पकड़ेंगे जहां पर्ल कुछ समय पहले था, जैसा कि अब है। सब कुछ एडवांस। यदि कुछ और नहीं, जहां पर्ल का नेतृत्व होता है, तो अन्य लोग भी इसका अनुसरण करते हैं। जब पर्ल एक बार फिर से सबके साथ हो जाएगा, तो पर्ल अब कहां है? मुझे कोई पता नहीं है, लेकिन मुझे पता है कि हम भी चले गए होंगे। संभवतः हम पर्लिंग शैली के पैटर्न के करीब होंगे ।

यदि आप उस तरह की चीज को पसंद करते हैं, लेकिन इसे पर्ल में इस्तेमाल करना चाहते हैं, तो आप दामियन कॉनवे के अद्भुत रेगेक्सपी :: ग्रामर मॉड्यूल में दिलचस्पी ले सकते हैं । यह पूरी तरह से भयानक है, और जो मैंने अपने कार्यक्रम में यहां किया है वह ऐसा लगता है जैसे कि मेरा आदिम है जैसा कि पैटर्न है कि लोग बिना व्हाट्सएप या अल्फाबेटिक आइडेंटिफ़ायर के एक साथ रटना करते हैं। इसकी जांच - पड़ताल करें!


सिंपल HTML Chunker

यहाँ पार्सर का पूरा स्रोत है जो मैंने इस पोस्टिंग की शुरुआत से केंद्रपीठ को दिखाया था।

मैं यह सुझाव नहीं दे रहा हूं कि आपको इसका परीक्षण एक कठोर परीक्षण वाले पार्सिंग वर्ग पर करना चाहिए। लेकिन मैं लोगों को यह दिखावा करते हुए थक गया हूं कि कोई भी HTML को regexes के साथ पार्स नहीं कर सकता क्योंकि वे नहीं कर सकते। आप स्पष्ट रूप से कर सकते हैं, और यह कार्यक्रम उस दावे का प्रमाण है।

बेशक, यह आसान नहीं है, लेकिन यह है संभव!

और ऐसा करने की कोशिश करना समय की भयावह बर्बादी है, क्योंकि अच्छी पार्सिंग कक्षाएं मौजूद हैं, जिनका उपयोग आपको इस कार्य के लिए करना चाहिएमनमाने ढंग से HTML पार्स करने की कोशिश कर रहे लोगों का सही जवाब यह नहीं है कि यह असंभव है। यह एक स्पष्ट और विवादास्पद जवाब है। सही और ईमानदार जवाब यह है कि उन्हें इसका प्रयास नहीं करना चाहिए क्योंकि यह खरोंच से पता लगाने के लिए बहुत परेशान है; वे एक पहिया है कि पूरी तरह से अच्छी तरह से काम करता है re backnvent करने के लिए अपनी पीठ तोड़ नहीं करना चाहिए।

दूसरी ओर, HTML जो कि एक प्रेडिक्टेबल सबसेट के भीतर आता है, रेगेक्स के साथ पार्स करना बेहद आसान है। यह कोई आश्चर्य नहीं है कि लोग उन्हें इस्तेमाल करने की कोशिश करते हैं, क्योंकि छोटी समस्याओं के लिए, खिलौना समस्याएं शायद, कुछ भी आसान नहीं हो सकता है। इसीलिए यह दो कामों को अलग करने के लिए महत्वपूर्ण है - विशिष्ट बनाम सामान्य - क्योंकि ये जरूरी नहीं कि समान दृष्टिकोण की मांग करते हैं।

मुझे आशा है कि HTML और रीगेक्स के बारे में सवालों का अधिक निष्पक्ष और ईमानदार उपचार देखने के लिए यहां भविष्य में होगा।

यहाँ मेरा HTML lexer है। यह एक मान्य पार्स करने की कोशिश नहीं करता है; यह सिर्फ शाब्दिक तत्वों की पहचान करता है। आप इसे HTML पार्सर की तुलना में HTML चंकर के रूप में अधिक सोच सकते हैं । यह टूटे हुए HTML की बहुत माफी नहीं है, हालांकि यह उस दिशा में कुछ बहुत छोटे भत्ते बनाता है।

यहां तक ​​कि अगर आप कभी भी पूर्ण एचटीएमएल खुद को पार्स नहीं करते हैं (और आपको क्यों करना चाहिए? यह एक हल की गई समस्या है!), इस कार्यक्रम में बहुत अच्छे रेगेक्स बिट्स हैं जो मुझे विश्वास है कि बहुत से लोग बहुत कुछ सीख सकते हैं। का आनंद लें!

#!/usr/bin/env perl
#
# chunk_HTML - a regex-based HTML chunker
#
# Tom Christiansen <tchrist@perl.com
#   Sun Nov 21 19:16:02 MST 2010
########################################

use 5.012;

use strict;
use autodie;
use warnings qw< FATAL all >;
use open     qw< IN :bytes OUT :utf8 :std >;

MAIN: {
  $| = 1;
  lex_html(my $page = slurpy());
  exit();
}

########################################################################
sub lex_html {
    our $RX_SUBS;                                        ###############
    my  $html = shift();                                 # Am I...     #
    for (;;) {                                           # forgiven? :)#
        given ($html) {                                  ###############
            last                when (pos || 0) >= length;
            printf "\@%d=",          (pos || 0);
            print  "doctype "   when / \G (?&doctype)  $RX_SUBS  /xgc;
            print  "cdata "     when / \G (?&cdata)    $RX_SUBS  /xgc;
            print  "xml "       when / \G (?&xml)      $RX_SUBS  /xgc;
            print  "xhook "     when / \G (?&xhook)    $RX_SUBS  /xgc;
            print  "script "    when / \G (?&script)   $RX_SUBS  /xgc;
            print  "style "     when / \G (?&style)    $RX_SUBS  /xgc;
            print  "comment "   when / \G (?&comment)  $RX_SUBS  /xgc;
            print  "tag "       when / \G (?&tag)      $RX_SUBS  /xgc;
            print  "untag "     when / \G (?&untag)    $RX_SUBS  /xgc;
            print  "nasty "     when / \G (?&nasty)    $RX_SUBS  /xgc;
            print  "text "      when / \G (?&nontag)   $RX_SUBS  /xgc;
            default {
                die "UNCLASSIFIED: " .
                  substr($_, pos || 0, (length > 65) ? 65 : length);
            }
        }
    }
    say ".";
}
#####################
# Return correctly decoded contents of next complete
# file slurped in from the <ARGV> stream.
#
sub slurpy {
    our ($RX_SUBS, $Meta_Tag_Rx);
    my $_ = do { local $/; <ARGV> };   # read all input

    return unless length;

    use Encode   qw< decode >;

    my $bom = "";
    given ($_) {
        $bom = "UTF-32LE" when / ^ \xFf \xFe \0   \0   /x;  # LE
        $bom = "UTF-32BE" when / ^ \0   \0   \xFe \xFf /x;  #   BE
        $bom = "UTF-16LE" when / ^ \xFf \xFe           /x;  # le
        $bom = "UTF-16BE" when / ^ \xFe \xFf           /x;  #   be
        $bom = "UTF-8"    when / ^ \xEF \xBB \xBF      /x;  # st00pid
    }
    if ($bom) {
        say "[BOM $bom]";
        s/^...// if $bom eq "UTF-8";                        # st00pid

        # Must use UTF-(16|32) w/o -[BL]E to strip BOM.
        $bom =~ s/-[LB]E//;

        return decode($bom, $_);

        # if BOM found, don't fall through to look
        #  for embedded encoding spec
    }

    # Latin1 is web default if not otherwise specified.
    # No way to do this correctly if it was overridden
    # in the HTTP header, since we assume stream contains
    # HTML only, not also the HTTP header.
    my $encoding = "iso-8859-1";
    while (/ (?&xml) $RX_SUBS /pgx) {
        my $xml = ${^MATCH};
        next unless $xml =~ m{              $RX_SUBS
            (?= encoding )  (?&name)
                            (?&equals)
                            (?&quote) ?
            (?<ENCODING>    (?&value)       )
        }sx;
        if (lc $encoding ne lc $+{ENCODING}) {
            say "[XML ENCODING $encoding => $+{ENCODING}]";
            $encoding = $+{ENCODING};
        }
    }

    while (/$Meta_Tag_Rx/gi) {
        my $meta = $+{META};

        next unless $meta =~ m{             $RX_SUBS
            (?= http-equiv )    (?&name)
                                (?&equals)
            (?= (?&quote)? content-type )
                                (?&value)
        }six;

        next unless $meta =~ m{             $RX_SUBS
            (?= content )       (?&name)
                                (?&equals)
            (?<CONTENT>         (?&value)    )
        }six;

        next unless $+{CONTENT} =~ m{       $RX_SUBS
            (?= charset )       (?&name)
                                (?&equals)
            (?<CHARSET>         (?&value)    )
        }six;

        if (lc $encoding ne lc $+{CHARSET}) {
            say "[HTTP-EQUIV ENCODING $encoding => $+{CHARSET}]";
            $encoding = $+{CHARSET};
        }
    }

    return decode($encoding, $_);
}
########################################################################
# Make sure to this function is called
# as soon as source unit has been compiled.
UNITCHECK { load_rxsubs() }

# useful regex subroutines for HTML parsing
sub load_rxsubs {

    our $RX_SUBS = qr{
      (?(DEFINE)

        (?<WS> \s *  )

        (?<any_nv_pair>     (?&name) (?&equals) (?&value)         )
        (?<name>            \b (?=  \pL ) [\w:\-] +  \b           )
        (?<equals>          (?&WS)  = (?&WS)    )
        (?<value>           (?&quoted_value) | (?&unquoted_value) )
        (?<unwhite_chunk>   (?: (?! > ) \S ) +                    )

        (?<unquoted_value>  [\w:\-] *                             )

        (?<any_quote>  ["']      )

        (?<quoted_value>
            (?<quote>   (?&any_quote)  )
            (?: (?! \k<quote> ) . ) *
            \k<quote>
        )

        (?<start_tag>       < (?&WS)      )
        (?<html_end_tag>      >           )
        (?<xhtml_end_tag>   / >           )
        (?<end_tag>
            (?&WS)
            (?: (?&html_end_tag)
              | (?&xhtml_end_tag) )
         )

        (?<tag>
            (?&start_tag)
            (?&name)
            (?:
                (?&WS)
                (?&any_nv_pair)
            ) *
            (?&end_tag)
        )

        (?<untag> </ (?&name) > )

        # starts like a tag, but has screwed up quotes inside it
        (?<nasty>
            (?&start_tag)
            (?&name)
            .*?
            (?&end_tag)
        )

        (?<nontag>    [^<] +            )

        (?<string> (?&quoted_value)     )
        (?<word>   (?&name)             )

        (?<doctype>
            <!DOCTYPE
                # please don't feed me nonHTML
                ### (?&WS) HTML
            [^>]* >
        )

        (?<cdata>   <!\[CDATA\[     .*?     \]\]    > )
        (?<script>  (?= <script ) (?&tag)   .*?     </script> )
        (?<style>   (?= <style  ) (?&tag)   .*?     </style> )
        (?<comment> <!--            .*?           --> )

        (?<xml>
            < \? xml
            (?:
                (?&WS)
                (?&any_nv_pair)
            ) *
            (?&WS)
            \? >
        )

        (?<xhook> < \? .*? \? > )

      )

    }six;

    our $Meta_Tag_Rx = qr{                          $RX_SUBS
        (?<META>
            (?&start_tag) meta \b
            (?:
                (?&WS) (?&any_nv_pair)
            ) +
            (?&end_tag)
        )
    }six;

}

# nobody *ever* remembers to do this!
END { close STDOUT }

23
आपकी टिप्पणी से दो हाइलाइट "मैं हर समय पार्सिंग कक्षाओं का उपयोग करता हूं, खासकर अगर यह HTML है कि मैंने खुद को उत्पन्न नहीं किया है।" और "पैटर्न को बदसूरत होने की ज़रूरत नहीं है, और उन्हें कठोर होने की ज़रूरत नहीं है। यदि आप बदसूरत पैटर्न बनाते हैं, तो यह आप पर प्रतिबिंब है, न कि उन्हें।" मैं पूरी तरह से सहमत हूं कि आपने क्या कहा है, इसलिए मैं समस्या का पुनर्मूल्यांकन कर रहा हूं। इस तरह के विस्तृत उत्तर के लिए बहुत बहुत धन्यवाद
सलमान

168
जो लोग नहीं जानते हैं, मैंने सोचा कि मैं उल्लेख करूंगा कि टॉम "प्रोग्रामिंग पर्ल" (उर्फ कैमल बुक) के सह-लेखक हैं और शीर्ष पर्ल अधिकारियों में से एक हैं। यदि आपको संदेह है कि यह असली टॉम क्रिस्टियन है, तो वापस जाएं और पोस्ट पढ़ें।
बिल रुपेर्ट

20
योग करने के लिए: RegEx के गलत नाम हैं। मुझे लगता है कि यह शर्म की बात है, लेकिन यह नहीं बदलेगा। संगत 'RegEx' इंजनों को गैर-नियमित भाषाओं को अस्वीकार करने की अनुमति नहीं है। इसलिए उन्हें केवल Finte State Machines के साथ सही तरीके से लागू नहीं किया जा सकता है। कम्प्यूटेशनल कक्षाओं के आसपास शक्तिशाली अवधारणाएं लागू नहीं होती हैं। RegEx का उपयोग O (n) निष्पादन समय सुनिश्चित नहीं करता है। RegEx के फायदों में सिंटैक्स और वर्ण पहचान के निहित डोमेन हैं। मेरे लिए, यह एक धीमी गति से चलती ट्रेन मलबे है, दूर देखने के लिए असंभव है, लेकिन भयानक परिणाम सामने आते हैं।
स्टीव स्टीनर

27
@ टीचर, यह ओपी मूल प्रश्न का उत्तर नहीं देता है। और है पार्स करने उचित शब्द यहाँ? Afaics regex tokenizing / lexical विश्लेषण कर रहे हैं, लेकिन अंतिम पार्सल कोड के साथ किया जाता है, खुद regex नहीं।
Qtax 15

65
@tchrist बहुत प्रभावशाली है। आप स्पष्ट रूप से एक उच्च कुशल और प्रतिभाशाली पर्ल प्रोग्रामर हैं, और आधुनिक नियमित अभिव्यक्ति के बारे में बेहद जानकार हैं। मैं यह बताना चाहूंगा कि आपने जो लिखा है, वह वास्तव में एक नियमित अभिव्यक्ति (आधुनिक, नियमित, या अन्यथा) नहीं है, बल्कि एक पर्ल प्रोग्राम है जो नियमित अभिव्यक्ति का भारी उपयोग करता है। क्या आपकी पोस्ट वास्तव में इस दावे का समर्थन करती है कि नियमित अभिव्यक्ति HTML को सही ढंग से पार्स कर सकती है? या यह सबूत की तरह अधिक है कि पर्ल HTML को सही ढंग से पार्स कर सकता है? किसी भी तरह से, अच्छा काम!
माइक क्लार्क

126
  1. आप एक उपन्यास लिख सकते हैं जैसे कि tchrist ने किया
  2. आप DOM लाइब्रेरी का उपयोग कर सकते हैं, HTML लोड कर सकते हैं और xpath का उपयोग कर सकते हैं और उपयोग कर सकते हैं //input[@type="hidden"]। या यदि आप xpath का उपयोग नहीं करना चाहते हैं, तो बस सभी इनपुट और फ़िल्टर प्राप्त करें, जिनके साथ छिपा हुआ है getAttribute

मुझे # 2 पसंद है।

<?php

$d = new DOMDocument();
$d->loadHTML(
    '
    <p>fsdjl</p>
    <form><div>fdsjl</div></form>
    <input type="hidden" name="blah" value="hide yo kids">
    <input type="text" name="blah" value="hide yo kids">
    <input type="hidden" name="blah" value="hide yo wife">
');
$x = new DOMXpath($d);
$inputs = $x->evaluate('//input[@type="hidden"]');

foreach ( $inputs as $input ) {
    echo $input->getAttribute('value'), '<br>';
}

परिणाम:

hide yo kids<br>hide yo wife<br>

72
यह वास्तव में मेरी बात थोड़े था। मैं दिखाना चाहता था कि यह कितना कठिन है।
त्रिशूल

19
वहां बहुत अच्छा सामान। मुझे वास्तव में उम्मीद थी कि लोग यह दर्शाएंगे कि पर्सिंग क्लास का उपयोग करना कितना आसान है, इसलिए धन्यवाद! मैं सिर्फ चरम समस्या का एक कामकाजी उदाहरण चाहता था जिसे आपको रेक्सक्स का उपयोग करके खरोंच से करना है। मुझे यकीन है कि आशा है कि ज्यादातर लोग जेनेरिक HTML पर प्रीफ़ैब पार्सर का उपयोग करने के बजाय अपने स्वयं के रोल करने के लिए निष्कर्ष निकालते हैं। Regexes अभी भी साधारण एचटीएमएल के लिए महान हैं जो उन्होंने स्वयं बनाए, हालांकि, क्योंकि 99.98% जटिलता से छुटकारा मिलता है।
tchrist

5
उन 2 बहुत ही रोचक दृष्टिकोणों को पढ़ने के बाद क्या अच्छा होगा, एक दूसरे के खिलाफ एक दृष्टिकोण की गति / मेमोरी उपयोग / सीपीयू की तुलना होगी (यानी रेगेक्स-आधारित वीएस पार्सिंग क्लास)।
the_yellow_logo

1
@ Avt'W हाँ, ऐसा नहीं है कि आपको एक 'उपन्यास' लिखना चाहिए अगर Regexes तेजी से हो, लेकिन वास्तव में यह वास्तव में जानना दिलचस्प होगा। :) लेकिन मेरा अनुमान पहले से ही है, कि एक पार्सर कम संसाधन लेता है, ..
डेनिस 98

यह वास्तव में क्यों XPath पहली जगह में आविष्कार किया गया था!
थोरबजोरन रावन एंडरसन

21

टॉम क्रिस्टियनसेन के लेक्सर समाधान की भावना में, यहां रॉबर्ट कैमरून के 1998 के लेख, आरईएक्स: एक्सएमएल शैलो पार्सिंग विद रेग्युलर एक्सप्रेशंस का लिंक दिया गया है

http://www.cs.sfu.ca/~cameron/REX.html

सार

एक्सएमएल का सिंटैक्स इतना सरल है कि एक एक्सएमएल दस्तावेज़ को अपने मार्कअप और टेक्स्ट आइटम की सूची में एकल नियमित अभिव्यक्ति का उपयोग करके पार्स करना संभव है। XML दस्तावेज़ का एक उथला पार्स विभिन्न प्रकार के हल्के XML प्रसंस्करण टूल के निर्माण के लिए बहुत उपयोगी हो सकता है। हालांकि, जटिल नियमित अभिव्यक्तियों का निर्माण करना मुश्किल हो सकता है और पढ़ने के लिए और भी मुश्किल हो सकता है। नियमित अभिव्यक्ति के लिए साक्षर प्रोग्रामिंग के एक रूप का उपयोग करते हुए, यह पेपर XML उथले पार्सिंग अभिव्यक्तियों का एक दस्तावेज है, जिसका उपयोग सरल, सही, कुशल, मजबूत और भाषा-स्वतंत्र XML उथले पार्सिंग के लिए एक आधार के रूप में किया जा सकता है। पर्ल, जावास्क्रिप्ट और लेक्स / फ्लेक्स में से प्रत्येक में 50 से कम लाइनों के पूर्ण उथले पार्सर कार्यान्वयन भी दिए गए हैं।

यदि आप नियमित अभिव्यक्ति के बारे में पढ़ने का आनंद लेते हैं, तो कैमरन का पेपर आकर्षक है। उनका लेखन संक्षिप्त, संपूर्ण और बहुत विस्तृत है। वह केवल आपको यह नहीं दिखा रहा है कि आरईएक्स नियमित अभिव्यक्ति का निर्माण कैसे करें, बल्कि छोटे भागों से किसी भी जटिल regex के निर्माण के लिए एक दृष्टिकोण भी है।

मैं 10 वर्षों से REX की नियमित अभिव्यक्ति का उपयोग कर रहा हूं और समस्या के समाधान के लिए प्रारंभिक पोस्टर के बारे में पूछा गया है (मैं इस विशेष टैग से कैसे मेल खाता हूं लेकिन कुछ अन्य समान टैग नहीं?)। मैं regex वह पूरी तरह से विश्वसनीय हो विकसित किया है।

REX विशेष रूप से तब उपयोगी होता है जब आप किसी दस्तावेज़ के शाब्दिक विवरण पर ध्यान केंद्रित कर रहे हों - उदाहरण के लिए, जब एक प्रकार का टेक्स्ट दस्तावेज़ (जैसे, सादा पाठ, XML, SGML, HTML) को दूसरे में परिवर्तित किया जाता है, जहाँ दस्तावेज़ मान्य नहीं हो सकता है, अधिकांश परिवर्तन के लिए अच्छी तरह से गठित, या यहाँ तक कि पार्स करने योग्य भी। यह आपको दस्तावेज़ के बाकी हिस्सों को परेशान किए बिना कहीं भी मार्कअप के द्वीपों को लक्षित करने देता है।


7

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

मैं रेगेक्स का बहुत बड़ा प्रस्तावक हूं, जब इसे सही तरीके से इस्तेमाल किया जाता है। लेकिन कलंक (और प्रदर्शन) के कारण, मैं हमेशा बताता हूं कि अच्छी तरह से बनाई गई XML या HTML एक XML पार्सर का उपयोग करना चाहिए। और भी बेहतर प्रदर्शन स्ट्रिंग-पार्सिंग होगा, हालांकि पठनीयता के बीच एक रेखा होती है अगर वह बहुत अधिक बाहर हो जाती है। हालाँकि, यह सवाल नहीं है। सवाल यह है कि छिपे हुए प्रकार के इनपुट टैग का मिलान कैसे किया जाए। उत्तर है:

<input[^>]*type="hidden"[^>]*>

आपके स्वाद के आधार पर, केवल regex विकल्प जिसे आपको शामिल करना होगा, वह है ignorecase विकल्प।


5
<input type='hidden' name='Oh, <really>?' value='Try a real HTML parser instead.'>
इल्मरी करोनें

4
आपका उदाहरण स्व-समापन है। /> के साथ समाप्त होना चाहिए। इसके अलावा, जबकि >नाम क्षेत्र में होने की संभावना लगभग कोई भी नहीं है, वास्तव >में एक्शन हैंडल में होना संभव है। ईजी: ऑनलाइन संपत्ति पर इनलाइन जावास्क्रिप्ट कॉल। कहा जा रहा है कि, मेरे पास उन लोगों के लिए एक XML पार्सर है, लेकिन उन लोगों के लिए एक रेग्क्स भी है जहां मुझे जो दस्तावेज़ दिया गया है वह XML पार्सर्स को संभालने के लिए बहुत गड़बड़ है, लेकिन एक रेग्क्स कर सकते हैं। इसके अलावा, यह वह नहीं है जो सवाल था। आप इन स्थितियों में छिपे इनपुट के साथ कभी नहीं चलेंगे, और मेरा उत्तर सबसे अच्छा है। Ya, <really>!
सुमेर

3
/>एक XML-ism है; यह HTML के किसी भी संस्करण में आवश्यक नहीं है, एक्सएचटीएमएल को छोड़कर (जो वास्तव में कभी भी बहुत अधिक कर्षण प्राप्त नहीं करता है, और एचटीएमएल 5 द्वारा अलंकृत किया गया है)। और आप सही गंदा का एक बहुत नहीं-सच-मान्य HTML यह है कि वहाँ बाहर है, लेकिन एक अच्छा (एचटीएमएल नहीं एक्सएमएल) पार्सर इसमें से अधिकांश के साथ सामना करने में सक्षम होना चाहिए; यदि वे नहीं करते हैं, तो सबसे अधिक संभावना है कि न तो ब्राउज़र्स होंगे।
इल्मरी करोनें

1
यदि केवल पार्सिंग या आपकी ज़रूरत की खोज छिपे हुए इनपुट फ़ील्ड के संग्रह को वापस करने के लिए एकल हिट है, तो यह रेगेक्स सही होगा। .NET XML डॉक्यूमेंट क्लास (तों) का उपयोग करना, या केवल एक विधि को कॉल करने के लिए एक थ्रिड पार्टी XML / HTML पार्सर का संदर्भ देना जब रेगेक्स का निर्माण किया जाता है तो यह ओवरकिल हो जाएगा। और आप सही हैं कि एक वेबसाइट ने इतना गड़बड़ कर दिया है कि एक अच्छा एचटीएमएल। पार्सर इसे संभाल नहीं सकता है शायद यह भी कुछ ऐसा नहीं है जिसे एक देव देख रहा होगा। लेकिन मेरी कंपनी को हर महीने लाखों पृष्ठ दिए जाते हैं जो कि कई बार संक्षिप्त और लच्छेदार होते हैं जैसे कि कभी-कभी (हमेशा नहीं), Regex सबसे अच्छा विकल्प है।
सुमेर

1
केवल यह कहा जा रहा है कि हम पूरी कंपनी के बारे में निश्चित नहीं हैं क्योंकि यह देव यह उत्तर चाहता है। लेकिन यह वह है जो उसने मांगा।
सुमेरे

3

आप यह कोशिश कर सकते हैं:

<[A-Za-z ="/_0-9+]*>

और करीब परिणाम के लिए आप यह कोशिश कर सकते हैं:

<[ ]*input[ ]+type="hidden"[ ]*name=[A-Za-z ="_0-9+]*[ ]*[/]*>

आप यहाँ अपने regex पैटर्न का परीक्षण कर सकते हैं http://regexpal.com/

इसके लिए ये pattens अच्छे हैं:

<input type="hidden" name="SaveRequired" value="False" /><input type="hidden" name="__VIEWSTATE1" value="1H4sIAAtzrkX7QfL5VEGj6nGi+nP" /><input type="hidden" name="__VIEWSTATE2" value="0351118MK" /><input type="hidden" name="__VIEWSTATE3" value="ZVVV91yjY" />

और के यादृच्छिक क्रम के लिए type, nameऔर valueयू इस का उपयोग कर सकते हैं:

<[ ]*input[ ]*[A-Za-z ="_0-9+/]*>

या

<[ ]*input[ ]*[A-Za-z ="_0-9+/]*[ ]*[/]>

इस पर :

<input  name="SaveRequired" type="hidden" value="False" /><input type="hidden" name="__VIEWSTATE1" value="1H4sIAAtzrkX7QfL5VEGj6nGi+nP" /><input type="hidden" name="__VIEWSTATE2" value="0351118MK" /><input  name="__VIEWSTATE3" type="hidden" value="ZVVV91yjY" />

`

वैसे मुझे लगता है कि आप कुछ इस तरह चाहते हैं:

<[ ]*input(([ ]*type="hidden"[ ]*name=[A-Za-z0-9_+"]*[ ]*value=[A-Za-z0-9_+"]*[ ]*)+)[ ]*/>|<[ ]*input(([ ]*type="hidden"[ ]*value=[A-Za-z0-9_+"]*[ ]*name=[A-Za-z0-9_+"]*[ ]*)+)[ ]*/>|<[ ]*input(([ ]*name=[A-Za-z0-9_+"]*[ ]*type="hidden"[ ]*value=[A-Za-z0-9_+"]*[ ]*)+)[ ]*/>|<[ ]*input(([ ]*value=[A-Za-z0-9_+"]*[ ]*type="hidden"[ ]*name=[A-Za-z0-9_+"]*[ ]*)+)[ ]*/>|<[ ]*input(([ ]*name=[A-Za-z0-9_+"]*[ ]*value=[A-Za-z0-9_+"]*[ ]*type="hidden"[ ]*)+)[ ]*/>|<[ ]*input(([ ]*value=[A-Za-z0-9_+"]*[ ]*name=[A-Za-z0-9_+"]*[ ]*type="hidden"[ ]*)+)[ ]*/>

यह अच्छा नहीं है, लेकिन यह किसी भी तरह से काम करता है।

इसका परीक्षण करें: http://regexpal.com/


1

मैं **DOMDocument**html कोड निकालने के लिए उपयोग करना चाहूंगा ।

$dom = new DOMDocument();
$dom ->loadHTML($input);
$x = new DOMXpath($dom );
$results = $x->evaluate('//input[@type="hidden"]');

foreach ( $results as $item) {
    print_r( $item->getAttribute('value') );
}

BTW, आप इसे यहाँ में परीक्षण कर सकते हैं - regex101.com। यह वास्तविक समय में परिणाम दिखाता है। Regexp के बारे में कुछ नियम: http://www.eclipse.org/tptp/home/downloads/installguide/gla_42/ref/rregexp.html रीडर


0

मान लें कि आपका html सामग्री स्ट्रिंग html में संग्रहीत है, ताकि हर इनपुट को प्राप्त करने के लिए जिसमें आप छिपे हुए प्रकार का उपयोग कर सकें, आप नियमित अभिव्यक्ति का उपयोग कर सकते हैं

var regex = /(<input.*?type\s?=\s?["']hidden["'].*?>)/g;
html.match(regex);

उपरोक्त रेगेक्स <inputकिसी भी संख्या के वर्णों का अनुसरण करता है, जब तक कि यह नहीं मिलता है type="hidden"या टाइप करता है = 'छिपा हुआ' किसी भी संख्या में वर्णों के बाद तक इसे प्राप्त करता है>

/ g दिए गए पैटर्न से मेल खाने वाले प्रत्येक प्रतिस्थापन को खोजने के लिए नियमित अभिव्यक्ति बताएं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.