নিয়মিত প্রকাশের প্যাটার্ন স্ট্রিংয়ের সাথে কোথাও মেলে না?


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>ট্যাগের বৈশিষ্ট্যগুলির অবস্থান নির্বিশেষে মেলে ?

PS: উপায় দ্বারা আমি নিয়মিত অভিব্যক্তি পরীক্ষার জন্য অ্যাডোব এয়ার ভিত্তিক RegEx ডেস্কটপ সরঞ্জামটি ব্যবহার করছি।


4
উত্সাহিত এইচটিএমএলটির নিয়ন্ত্রণ যদি আপনার থাকে তবে রেজেক্সটি দুর্দান্ত সমাধান কারণ এটি নিয়মিত বিতর্ক নয় বরং নিয়মিত, তবে আমার ক্ষেত্রে আমি জানি না যে এইচটিএমএল ভবিষ্যতে কীভাবে পরিবর্তিত হতে চলেছে তাই সেরা জিনিসটি রেজেক্সের পরিবর্তে পার্সার ব্যবহার করা উচিত, আমি ব্যবহার করেছি আমার প্রজেক্টে যে অংশগুলির উপর আমার নিয়ন্ত্রণ রয়েছে সেগুলিতে রেজেক্স
সালমান

উত্তর:


108

এখানে সমস্ত উত্তরের বিপরীতে, আপনি যা করতে চাইছেন সেই জন্য একটি সঠিক বৈধ সমাধান re এটি কারণ আপনি ভারসাম্য ট্যাগগুলির সাথে মেলে না চেষ্টা করছেন reএইহেতু রেইগেক্সের সাথে অসম্ভব! তবে আপনি কেবল একটি ট্যাগে যা মেলছেন তা পুরোপুরি নিয়মিত।

যদিও সমস্যাটি এখানে। আপনি এটি কেবল একটি রেইজেক্সের সাহায্যে করতে পারবেন না ... একটি <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
}

এখানে মূল নীতিটি হ'ল একটি নিয়মিত অভিব্যক্তি দিয়ে খুব বেশি কিছু করার চেষ্টা করবেন না। যেমন আপনি লক্ষ্য করেছেন, নিয়মিত প্রকাশগুলি একটি নির্দিষ্ট পরিমাণ অর্ডার প্রয়োগ করে। সুতরাং এর পরিবর্তে আপনার যা করা দরকার তা হ'ল প্রথমে আপনি কী কী উত্তোলনের চেষ্টা করছেন তার কনটেক্সটটির সাথে মেলে, তারপরে আপনি যে ডেটা চান তার উপর সাবম্যাচিং করুন।

সম্পাদনা: তবে, আমি সম্মত হব যে সাধারণভাবে এইচটিএমএল পার্সার ব্যবহার করা সম্ভবত সহজ এবং ভাল এবং আপনার কোডটি পুনরায় ডিজাইনিং করা বা আপনার উদ্দেশ্যগুলি পুনরায় পরীক্ষা করা উচিত। :-) তবে আমি এই উত্তরটি হাঁটুর জড়িত প্রতিক্রিয়াটির পাল্টা হিসাবে পোস্ট করতে হয়েছিল যে এইচটিএমএলের কোনও উপসেট পার্স করা অসম্ভব: আপনি সম্পূর্ণ স্পেসিফিকেশন বিবেচনা করার সময় এইচটিএমএল এবং এক্সএমএল উভয়ই অনিয়মিত, তবে একটি ট্যাগের স্পেসিফিকেশন শালীনভাবে নিয়মিত অবশ্যই পিসিআরই এর শক্তির মধ্যে।


14
এখানে সমস্ত উত্তর বিপরীতে নয় । :)
tchrist

6
@ ক্রিশ্চট: আমার পোস্ট করার সময় আপনার উত্তর এখানে ছিল না। ;-)
প্ল্যাটিনাম আজুর

7
হ্যাঁ ভাল - কোনও কারণে আপনার টাইপের চেয়ে টাইপ করতে আমার বেশি সময় লেগেছে। আমি মনে করি আমার কীবোর্ডের গ্রিসিংয়ের প্রয়োজন। :)
tchrist

6
এটি অবৈধ এইচটিএমএল - এটির মান হওয়া উচিত "" & lt; আপনি কি সত্যই এটি সম্পর্কে নিশ্চিত? & Gt; " যদি তিনি যে জায়গাটি স্ক্র্যাপ করছেন তার জন্য যদি এটি কোনও খারাপ কাজ থেকে দূরে থাকে তবে তার জন্য আরও একটি পরিশীলিত সমাধানের প্রয়োজন হবে - তবে যদি তারা এটি সঠিকভাবে করেন তবে (এবং যদি তার উপর এটি নিয়ন্ত্রণ থাকে তবে তার অবশ্যই এটি সঠিক হওয়া উচিত) তবে সে ঠিক আছে।
রস স্নাইডার

14
বিষয়টিতে সেরা এসও উত্তরের বাধ্যতামূলক লিঙ্ক (সম্ভবত সেরা এসও উত্তর পিরিয়ড): স্ট্যাকওভারফ্লো
ড্যানিয়েল রিবেইরো

682

ওহ হ্যাঁ আপনি এইচটিএমএল পার্স করতে রেজেক্সস ব্যবহার করতে পারেন !

আপনি যে কাজের জন্য চেষ্টা করছেন তার জন্য, রেজেক্সগুলি পুরোপুরি ঠিক আছে!

এটা তোলে হয় সত্য যে অধিকাংশ লোক রেগুলার এক্সপ্রেশনের সাথে পার্সিং 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);
    }
  }
}

এটি পড়তে কত সহজ ?

যেমনটি লেখা আছে, এটি এইচটিএমএল এর প্রতিটি টুকরো চিহ্নিত করে এবং এটি কোথায় টুকরোটি খুঁজে পেয়েছে তা জানায়। আপনি যে কোনও প্রকারের টুকরো দিয়ে যা চান তা করতে বা এগুলির চেয়ে আরও বিশেষ ধরণের জন্য খুব সহজেই এটি পরিবর্তন করতে পারেন।

আমার কোনও ব্যর্থ পরীক্ষার কেস নেই (বাম :): আমি এই কোডটি সফলভাবে 100,000 এরও বেশি এইচটিএমএল ফাইলে চালিয়েছি - প্রত্যেকটিই আমি দ্রুত এবং সহজেই আমার হাত পেতে পারি। এর বাইরেও আমি এটিকে বিশেষত ভ্রান্ত পার্সার ভাঙার জন্য নির্মিত ফাইলগুলিতে চালিয়েছি।

এই না একটি সাদাসিধা পার্সার।

ওহ, আমি নিশ্চিত এটি নিখুঁত নয়, তবে আমি এখনও এটি ভেঙে ফেলতে পারি নি। আমি অনুমান করেছি যে কিছু করা হলেও, সমাধানটি প্রোগ্রামের সুস্পষ্ট কাঠামোর কারণে মাপসই করা সহজ হবে। এমনকি রিজেক্স-ভারী প্রোগ্রামগুলির স্টাকচার হওয়া উচিত।

এখন যে উপায় বাইরে, আমাকে ওপি এর প্রশ্নে সম্বোধন করা যাক।

রেজিক্সগুলি ব্যবহার করে ওপির টাস্ক সলভ করার ডেমো

html_input_rxআমি নীচে অন্তর্ভুক্ত করা ছোট্ট প্রোগ্রামটি নিম্নলিখিত আউটপুট উত্পাদন করে, যাতে আপনি দেখতে পাচ্ছেন যে রেজেক্সেস সহ পার্সিং এইচটিএমএল আপনি যা করতে চান তার জন্য ঠিক কাজ করে:

% 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: $!";
} 

এই নাও! কিছুই নেই! :)

রেগেক্সেস সহ আপনার দক্ষতা কোনও বিশেষ পার্সিংয়ের উপর নির্ভর করে কিনা তা আপনি কেবল বিচার করতে পারেন। প্রত্যেকের দক্ষতার স্তর আলাদা এবং প্রতিটি নতুন কাজ আলাদা। যে কাজের ক্ষেত্রে আপনার সু-সংজ্ঞায়িত ইনপুট সেট রয়েছে, রেজিক্সগুলি স্পষ্টতই সঠিক পছন্দ, কারণ যখন আপনার সাথে ডিল করার জন্য এইচটিএমএলের একটি সীমাবদ্ধ সাবসেট থাকে তখন কিছু একসাথে রাখা তুচ্ছ। এমনকি রিজেক্স নব্বইয়েরদেরও সেই কাজগুলি রেজিক্স সহ পরিচালনা করা উচিত। আর কিছু হ'ল ওভারকিল।

যাইহোক , এইচটিএমএল একবারে কম পেরেক হয়ে উঠতে শুরু করলে, একবার আপনি যেভাবে ভবিষ্যদ্বাণী করতে পারবেন না এমনভাবে ছড়িয়ে পড়তে শুরু করে তবে যা পুরোপুরি আইনী, একবার আপনাকে আরও বিভিন্ন ধরণের জিনিস বা আরও জটিল নির্ভরতার সাথে মিলিয়ে ফেললে আপনি অবশেষে এমন একটি জায়গায় পৌঁছে যাবেন where পার্সিং ক্লাসটি ব্যবহার করার চেয়ে আপনাকে রেজিক্সগুলি ব্যবহার করে এমন একটি সমাধান কার্যকর করতে আপনাকে আরও কঠোর পরিশ্রম করতে হবে। যেখানে বিরতি-সমান পয়েন্ট ফলস আবার আপনার নিজের স্বাচ্ছন্দ্যের স্তরের উপর পুনরায় নির্ভর করে ge

তো এখন আমার কি করা উচিৎ?

আপনাকে কী করতে হবে বা আপনি কী করতে পারবেন না তা আমি আপনাকে বলব না। আমি মনে করি এটি ভুল। আমি আপনাকে কেবল সম্ভাব্যতার সাথে উপস্থাপন করতে চাই, আপনার চোখ কিছুটা খুলুন। আপনি কী করতে চান এবং আপনি এটি কীভাবে করতে চান তা চয়ন করতে পারেন। কোনও রহস্য নেই - এবং আপনি নিজের মতো করে নিজের পরিস্থিতি অন্য কেউ জানে না। যদি কিছু মনে হয় এটি খুব বেশি কাজ, ভাল, সম্ভবত এটি। প্রোগ্রামিং মজা করা উচিত , আপনি জানেন। যদি এটি না হয় তবে আপনি এটি ভুল করছেন।

আমার html_input_rxপ্রোগ্রামটি যে কোনও সংখ্যক বৈধ উপায়ে দেখে নেওয়া যেতে পারে। এর মধ্যে একটি হ'ল আপনি অবশ্যই নিয়মিত প্রকাশের সাথে এইচটিএমএলকে বিশ্লেষণ করতে পারেন । তবে আরেকটি হ'ল এটি যে প্রায় কেউ কখনও কখনও এটি মনে করে তার চেয়ে অনেক বেশি, অনেক বেশি। এটি সহজেই এই সিদ্ধান্তে পৌঁছে দিতে পারে যে আমার প্রোগ্রামটি আপনাকে যা করা উচিত নয় তার একটি প্রমাণ হিসাবে এটি সত্যিই খুব শক্ত।

আমি এর সাথে একমত হইব না। অবশ্যই আমি যদি আমার প্রোগ্রামে যা কিছু করি তা কিছু অধ্যয়নের পরে যদি আপনার কাছে তা বোঝায় না, তবে আপনাকে এই ধরণের কাজের জন্য রেজিেক্সগুলি ব্যবহার করার চেষ্টা করা উচিত নয়। নির্দিষ্ট এইচটিএমএল-এর জন্য, রেজেক্সগুলি দুর্দান্ত তবে জেনেরিক এইচটিএমএল-এর জন্য এগুলি উন্মাদনার সমতুল্য। আমি সমস্ত সময় পার্সিং ক্লাস ব্যবহার করি, বিশেষত এটি যদি এইচটিএমএল আমি নিজেই উত্পন্ন না করি।

ছোট এইচটিএমএল পার্সিং সমস্যাগুলির জন্য সর্বোত্তম রেজিেক্সস, বড়গুলির জন্য প্যাসিমাল

এমনকি যদি আমার প্রোগ্রামটি সাধারণ এইচটিএমএল পার্স করার জন্য কেন রেজিেক্সগুলি ব্যবহার করবেন না - উদাহরণস্বরূপ নেওয়া হয় - যা ঠিক আছে, কারণ আমি এটির জন্য এটি বোঝাতে চাইছিলাম - এটি এখনও একটি চোখ খোলা হওয়া উচিত যাতে আরও লোকেরা মারাত্মক সাধারণকে ভেঙে দেয় এবং অপঠনযোগ্য, কাঠামোগত, এবং অপ্রত্যাশিত নিদর্শনগুলি লেখার বাজে, বাজে অভ্যাস।

প্যাটার্নগুলি কুরুচিপূর্ণ হতে হবে না এবং তাদের কঠোর হতে হবে না। আপনি যদি কুৎসিত নিদর্শন তৈরি করেন তবে এটি আপনার প্রতিফলন, সেগুলি নয়।

উদ্ভট উত্সাহী রেজেক্স ভাষা

আমাকে উল্লেখ করতে বলা হয়েছে যে আপনার সমস্যার প্রতি আমার নিখুঁত সমাধান পার্লে লেখা হয়েছে। আপনি বিস্মিত? আপনি খেয়াল করেননি? এই উদ্ঘাটন কি একটি বোমাশেল?

এটি সত্য যে পার্লের মতো রেজিওসের ক্ষেত্রে অন্যান্য সমস্ত সরঞ্জাম এবং প্রোগ্রামিং ল্যাঙ্গুয়েজগুলি যথেষ্ট সুবিধাজনক, অভিব্যক্তিপূর্ণ এবং শক্তিশালী নয়। সেখানে একটি বড় বর্ণালী আছে, কিছু অন্যদের চেয়ে বেশি উপযুক্ত। সাধারণভাবে, যে ভাষাগুলি গ্রন্থাগার হিসাবে পরিবর্তে মূল ভাষার অংশ হিসাবে পুনরায় প্রকাশ করেছে তাদের সাথে কাজ করা সহজ। রেগেক্সেসের সাথে আমি এমন কিছুই করিনি যা আপনি করতে পারেননি, বলুন, পিসিআরই, যদিও আপনি সি ব্যবহার করছেন যদি আপনি প্রোগ্রামটি অন্যভাবে গঠন করেন although

শেষ পর্যন্ত অন্যান্য ভাষাগুলি যেখানে রেজেক্সেসের ক্ষেত্রে পার্ল এখন সেখানে তা ধরা পড়বে। আমি এটি বলছি কারণ যখন পার্ল শুরু হয়েছিল তখন কারও কারও কাছে পারেলের রেজিজেসের মতো কিছুই ছিল না। আপনার পছন্দের যেকোন কিছু বলুন, তবে পার্ল স্পষ্টতই এখানে জিতেছিলেন: প্রত্যেকে তাদের বিকাশের বিভিন্ন পর্যায়ে পার্লের রেজিজেসগুলি অনুলিপি করেছিল। পার্ল আপনি আজ যে কোনও সরঞ্জাম বা ভাষা ব্যবহার না করেই আধুনিক নকশায় নির্ভর করতে এসেছেন এমন প্রায় সমস্ত কিছু (প্রায় সবই নয়, প্রায়) অগ্রণীত করেছিলেন। তাই অবশেষে অন্যদের হবে ধরতে।

তবে তারা কেবল যেখানে পার্ল আগে একসময় ছিল ঠিক তেমনই ধরবে, যেমনটি এখন রয়েছে। সবকিছু অগ্রসর। রেজিজেসগুলিতে অন্য কিছু না থাকলে, যেখানে পার্ল নেতৃত্ব দেয়, অন্যরা অনুসরণ করে। পার্ল একবারে কোথায় থাকবে অন্য সবার শেষে অবশেষে পার্ল এখন কোথায় থাকবে? আমার কোনও ধারণা নেই, তবে আমি জানি আমরাও চলে এসেছি। সম্ভবত আমরা কারুকার্যকার্য ধরণের পার্লির স্টাইলের আরও কাছাকাছি থাকব

আপনি যদি এই ধরণের জিনিস পছন্দ করেন তবে এটি পার্লিতে ব্যবহার করতে চান, আপনি দামিয়ান কনওয়ের দুর্দান্ত রেজিএক্সএক্স :: ব্যাকরণ মডিউলটিতে আগ্রহী হতে পারেন । এটি সম্পূর্ণ দুর্দান্ত, এবং আমি এখানে আমার প্রোগ্রামে যা করেছি তা ঠিক আমার মতো আদিম বলে মনে হয় যে লোকেরা সাদা স্থান বা বর্ণমালা শনাক্তকারী ছাড়া একসাথে ক্র্যাম করে। এটা দেখ!


সাধারণ এইচটিএমএল চুনকার

এই পোস্টিংটির শুরুতে আমি কেন্দ্রীভূমিটি দেখিয়েছি পার্সারের সম্পূর্ণ উত্স।

আমি প্রস্তাব দিচ্ছি না যে আপনার এটি কঠোরভাবে পরীক্ষিত পার্সিং ক্লাসে ব্যবহার করা উচিত। কিন্তু আমি যে কেউ কিছু করতে পারেন পার্স এইচটিএমএল regexes মাত্র কারণ সঙ্গে ভান মানুষের ক্লান্ত তারা করতে পারেন না। আপনি পরিষ্কারভাবে পারেন এবং এই প্রোগ্রামটি সেই দৃ that়তার প্রমাণ।

নিশ্চিত, এটা সহজ নয়, কিন্তু এটা হয় সম্ভব!

এবং এটি করার চেষ্টা করা হ'ল একটি সময় নষ্ট করা, কারণ ভাল পার্সিং ক্লাস রয়েছে যা আপনার এই কাজের জন্য ব্যবহার করা উচিত । পার্স বের করার চেষ্টা লোকদের সঠিক উত্তর নির্বিচারে এইচটিএমএল হয় না এটি অসম্ভব। এটি একটি সহজ এবং জঘন্য উত্তর। সঠিক এবং সৎ উত্তরটি হ'ল তাদের চেষ্টা করা উচিত নয় কারণ স্ক্র্যাচ থেকে বের করা খুব বেশি বিরক্তিকর; পুরোপুরি ভালভাবে কাজ করে এমন একটি চাকা পুনরায় আবিষ্কার করার জন্য তাদের পিছনে ভাঙা উচিত নয়।

অন্যদিকে, এইচটিএমএল যা অনুমানযোগ্য সাবসেটের মধ্যে পড়ে তা হ'ল রেজিজেসগুলির সাথে পার্স করা অতি-সহজ। এতে আশ্চর্য হওয়ার কিছু নেই যে লোকেরা এগুলি ব্যবহার করার চেষ্টা করে, কারণ ছোট সমস্যাগুলির জন্য, খেলনা সমস্যার জন্য সম্ভবত কোনও কিছুই সহজ হতে পারে না। এই কারণেই দুটি কার্যের মধ্যে পার্থক্য করা এত গুরুত্বপূর্ণ - নির্দিষ্ট বনাম জেনেরিক - কারণ এগুলি অগত্যা একই পদ্ধতির চাহিদা রাখে না।

আমি ভবিষ্যতে আশা করি এইচটিএমএল এবং রেজিজেস সম্পর্কে প্রশ্নের আরও সুষ্ঠু ও সৎ আচরণ দেখতে।

এখানে আমার এইচটিএমএল লেক্সার। এটি একটি বৈধতা বিশ্লেষণ করার চেষ্টা করে না; এটি কেবল লেজিক উপাদানগুলি সনাক্ত করে। আপনি এটি 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
আপনার মন্তব্য থেকে দুটি হাইলাইট "আমি সর্বদা পার্সিং ক্লাস ব্যবহার করি, বিশেষত এটি যদি এইচটিএমএল আমি নিজেই উত্পন্ন না করি"। এবং "প্যাটার্নগুলি কুশ্রী হতে হবে না এবং সেগুলি কঠোর হতে হবে না you আপনি যদি কুরুচিপূর্ণ নমুনা তৈরি করেন তবে এটি আপনার প্রতিফলন, সেগুলি নয়" " আপনি যা বলেছেন তা আমি সম্পূর্ণরূপে একমত, তাই আমি সমস্যার মূল্যায়ন করছি। এই জাতীয় বিস্তারিত উত্তরের জন্য অনেক ধন্যবাদ
সালমান

168
যারা জানেন না তাদের জন্য, আমি ভেবেছিলাম যে আমি উল্লেখ করব যে টম হলেন "প্রোগ্রামিং পার্ল" (ওরফে উট বই) এর সহ-লেখক এবং শীর্ষ পার্ল কর্তৃপক্ষের একজন। আপনি যদি সন্দেহ করেন যে এটিই আসল টম ক্রিশ্চিয়ানসেন, ফিরে যান এবং পোস্টটি পড়ুন।
বিল রুপার্ট

20
সংক্ষেপে: RegEx গুলি ভুল করে রাখা হয়েছে। আমি মনে করি এটি লজ্জাজনক, তবে এটি পরিবর্তন হবে না। সামঞ্জস্যপূর্ণ 'রেজেক্স' ইঞ্জিনগুলিকে অ-নিয়মিত ভাষা প্রত্যাখ্যান করার অনুমতি নেই। সেহেতু কেবলমাত্র ফিনেটে স্টেট মেশিন দিয়ে এগুলি সঠিকভাবে প্রয়োগ করা যায় না। গণনা ক্লাসের চারপাশের শক্তিশালী ধারণা প্রয়োগ হয় না। RegEx এর ব্যবহার ও (এন) কার্যকর করার সময় নিশ্চিত করে না। RegEx এর সুবিধাগুলি হল সংক্ষিপ্ত সিনট্যাক্স এবং চরিত্র স্বীকৃতির অন্তর্ভুক্ত ডোমেন। আমার কাছে এটি ধীর গতি সম্পন্ন ট্রেনের ধ্বংসস্তূপ, দূরে সন্ধান করা অসম্ভব, তবে ভয়াবহ পরিণতি প্রকাশ পাচ্ছে।
স্টিভ স্টেইনার

27
@ ক্রিশ্চট, এটি কখনই ওপিএসের আসল প্রশ্নের উত্তর দেয় না। এবং এখানে উপযুক্ত শব্দটি বিশ্লেষণ করছে? আফিক্স রেজেক্স টোকনাইজিং / লেজিকাল এনালাইসিস করছেন, কিন্তু পার্ল কোড দিয়ে চূড়ান্ত বিশ্লেষণ করেছেন, রেজেক্স নিজেই নয়।
কিউট্যাক্স

65
@ টিচারিস্ট খুব চিত্তাকর্ষক। আপনি স্পষ্টতই একটি অত্যন্ত দক্ষ এবং প্রতিভাবান পার্ল প্রোগ্রামার, এবং আধুনিক নিয়মিত এক্সপ্রেশন সম্পর্কে অত্যন্ত জ্ঞানী। আমি উল্লেখ করতে চাই, যদিও, আপনি যা লিখেছেন তা কোনও নিয়মিত প্রকাশ (আধুনিক, নিয়মিত বা অন্যথায়) নয়, বরং পার্ল প্রোগ্রাম যা নিয়মিত প্রকাশকে প্রচুর পরিমাণে ব্যবহার করে। আপনার পোস্টটি কি এই দাবিটিকে সমর্থন করে যে নিয়মিত প্রকাশগুলি এইচটিএমএলকে সঠিকভাবে পার্স করতে পারে? অথবা এটি আরও প্রমাণের মতো যা পার্ল এইচটিএমএলকে সঠিকভাবে পার্স করতে পারে? যেভাবেই হোক, দুর্দান্ত কাজ!
মাইক ক্লার্ক

126
  1. আপনি যেমন ট্রাইস্টের মতো উপন্যাস লিখতে পারেন
  2. আপনি একটি ডিওএম লাইব্রেরি ব্যবহার করতে পারেন, এইচটিএমএল লোড করতে পারেন এবং এক্সপথ ব্যবহার করতে পারেন এবং কেবল ব্যবহার করতে পারেন //input[@type="hidden"]। অথবা আপনি যদি এক্সপথ ব্যবহার করতে না চান তবে কেবল সমস্ত ইনপুট পান এবং কোনটি লুকিয়ে থাকে তা ফিল্টার করুন 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
আসলে আমার বিন্দু ছিল। আমি কতটা শক্ত তা দেখাতে চেয়েছিলাম।
tchrist

19
খুব ভাল জিনিস সেখানে। আমি সত্যিই আশা করেছিলাম লোকেরা পার্সিং ক্লাসটি ব্যবহার করা কতটা সহজ তা দেখায়, তাই ধন্যবাদ! আমি কেবলমাত্র রেজিক্সগুলি ব্যবহার করে স্ক্র্যাচ থেকে এটি করতে গেলে আপনাকে যে চরম সমস্যায় পড়তে হবে তার একটি কার্যকারী উদাহরণ চাইছিলাম। আমি নিশ্চিত আশা করি বেশিরভাগ লোক জেনেরিক এইচটিএমএলগুলিতে নিজের ঘূর্ণায়মানের পরিবর্তে প্রেফাব পার্সার ব্যবহার করার সিদ্ধান্ত নিয়েছে। Regexes এখনও তারা নিজেরাই তৈরি করেছেন সাধারণ HTML এর জন্য এখনও দুর্দান্ত, কারণ এটি জটিলতার 99.98% থেকে মুক্তি পায়।
tchrist

5
2 টি খুব আকর্ষণীয় পদ্ধতির পড়ার পরে কী সুন্দর হবে তা অন্যটির বিরুদ্ধে এক পদ্ধতির গতি / মেমরির ব্যবহার / সিপিইউ (যেমন রেজেক্স ভিত্তিক ভিএস পার্সিং ক্লাস) এর সাথে তুলনা করবে।
the_yellow_logo

1
@ অ্যাভট'উ হ্যাঁ, রেজেক্সগুলি দ্রুত হতে দেখাতে আপনার একটি 'উপন্যাস' লেখার কথা নয়, তবে বাস্তবে এটি জেনে রাখা আকর্ষণীয় হবে। :) কিন্তু আমার অনুমান ইতিমধ্যে একটি পার্সার কম সম্পদ, খুব লাগে .. হয়,
Dennis98

এই কারণেই এক্সপথ প্রথম স্থানে উদ্ভাবিত হয়েছিল!
থোরবজর্ন রাভন অ্যান্ডারসন

21

টম ক্রিশ্চেনসেনের লিক্সার সলিউশনের চেতনায় রবার্ট ক্যামেরনের আপাতদৃষ্টিতে ভুলে যাওয়া ১৯৯৯ সালের নিবন্ধটির একটি লিঙ্ক, রেক্স: এক্সএমএল শ্যালো পার্সিং উইথ রেগুলার এক্সপ্রেশন।

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

বিমূর্ত

এক্সএমএলের বাক্য গঠনটি এত সহজ যে কোনও একক নিয়মিত অভিব্যক্তি ব্যবহার করে কোনও এক্সএমএল ডকুমেন্টকে তার মার্কআপ এবং পাঠ্য আইটেমের তালিকায় পার্স করা সম্ভব। এক্সএমএল ডকুমেন্টের এ জাতীয় অগভীর পার্স বিভিন্ন লাইটওয়েট এক্সএমএল প্রসেসিং সরঞ্জাম তৈরির জন্য খুব দরকারী। যাইহোক, জটিল নিয়মিত এক্সপ্রেশনগুলি নির্মাণ করা কঠিন এবং পড়া আরও জটিল difficult নিয়মিত অভিব্যক্তির জন্য একধরনের সাক্ষর প্রোগ্রামিং ব্যবহার করে, এই কাগজটি এক্সএমএল অগভীর পার্সিং এক্সপ্রেশনগুলির একটি সেট নথি করে যা সাধারণ, সঠিক, দক্ষ, দৃ rob় এবং ভাষা-স্বাধীন এক্সএমএল অগভীর পার্সিংয়ের জন্য ভিত্তি হিসাবে ব্যবহার করা যেতে পারে। পার্ল, জাভাস্ক্রিপ্ট এবং লেক্স / ফ্লেক্সের প্রতিটি 50 টিরও কম লাইনের সম্পূর্ণ অগভীর পার্সার বাস্তবায়ন দেওয়া হয়।

আপনি যদি নিয়মিত প্রকাশের বিষয়ে পড়া উপভোগ করেন তবে ক্যামেরনের কাগজটি আকর্ষণীয়। তাঁর লেখা সংক্ষিপ্ত, পুঙ্খানুপুঙ্খ, এবং খুব বিস্তারিত। তিনি কীভাবে আরএক্সের নিয়মিত অভিব্যক্তিটি তৈরি করবেন তা আপনাকে কেবল দেখিয়ে দিচ্ছেন না তবে ছোট অংশগুলি থেকে কোনও জটিল রেজেক্স তৈরির জন্য একটি পদ্ধতিরও।

প্রারম্ভিক পোস্টারটি জিজ্ঞাসা করা ধরণের সমস্যা সমাধানের জন্য আমি 10 বছর ধরে আরএক্সের নিয়মিত প্রকাশটি চালু এবং বন্ধ ব্যবহার করে আসছি (আমি কীভাবে এই নির্দিষ্ট ট্যাগটির সাথে মেলে তবে অন্য কোনও খুব অনুরূপ ট্যাগের সাথে নয়?) তিনি পুরোপুরি নির্ভরযোগ্য হিসাবে বিকাশিত রেগেক্সটি পেয়েছি।

REX বিশেষত কার্যকর যখন আপনি কোনও দস্তাবেজের বর্ণনামূলক বিশদগুলিতে ফোকাস করছেন - উদাহরণস্বরূপ, এক ধরণের পাঠ্য নথির (যেমন, সরল পাঠ্য, এক্সএমএল, এসজিএমএল, এইচটিএমএল) অন্যটিতে রূপান্তর করার সময়, যেখানে নথিটি বৈধ নয়, বেশিরভাগ রূপান্তরটির জন্য ভালভাবে গঠিত বা পার্সেবল। এটি আপনাকে অন্যান্য ডকুমেন্টকে বিরক্ত না করে কোনও ডকুমেন্টের মধ্যে মার্কআপের দ্বীপগুলিকে লক্ষ্য করতে দেয়।


7

যদিও আমি এই উত্তরগুলির বাক্যগুলির বিষয়বস্তুগুলি পছন্দ করি তবে তারা সরাসরি বা সঠিকভাবে প্রশ্নের উত্তর দেয়নি। এমনকি প্ল্যাটিনামের উত্তর অত্যধিক জটিল, এবং কম দক্ষও ছিল। সুতরাং আমি এই রাখা বাধ্য হয়েছিল।

আমি সঠিকভাবে ব্যবহৃত হলে আমি রেজেেক্সের বিশাল প্রবক্তা। তবে কলঙ্কের (এবং পারফরম্যান্স) কারণে আমি সবসময় বলে থাকি যে সুগঠিত এক্সএমএল বা এইচটিএমএলকে একটি এক্সএমএল পার্সার ব্যবহার করা উচিত। এমনকি আরও ভাল পারফরম্যান্স স্ট্রিং-পার্সিং হবে, যদিও পাঠযোগ্যতার মধ্যে একটি লাইন রয়েছে যদি তা খুব বেশি হাতছাড়া হয়ে যায়। যাইহোক, এটি প্রশ্ন নয়। প্রশ্নটি কীভাবে কোনও লুকানো-টাইপ ইনপুট ট্যাগের সাথে মেলে। উত্তরটা হচ্ছে:

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

আপনার স্বাদের উপর নির্ভর করে, আপনাকে কেবলমাত্র রেইগেক্স বিকল্পটি অন্তর্ভুক্ত করতে হবে তা হল উপেক্ষা করা বিকল্প।


5
<input type='hidden' name='Oh, <really>?' value='Try a real HTML parser instead.'>
ইলমারি করোনেন

4
আপনার উদাহরণটি স্ব-সমাপন। /> দিয়ে শেষ হওয়া উচিত। এছাড়াও, যখন >নাম ক্ষেত্রটিতে থাকার সম্ভাবনা প্রায় কোনওটিই নয়, তবে >অ্যাকশন হ্যান্ডেলটিতে এটি হওয়া সম্ভব । ইজি: অনক্লিক সম্পত্তিটিতে একটি ইনলাইন জাভাস্ক্রিপ্ট কল। বলা হচ্ছে যে, তাদের জন্য আমার কাছে এক্সএমএল পার্সার রয়েছে তবে আমি যে নথিটি দিয়েছি সেগুলি এক্সএমএল পার্সারদের পরিচালনা করার জন্য খুব গণ্ডগোলযুক্ত, তবে তাদের জন্য একটি রেজেেক্সও রয়েছে তবে একটি রেজেক্স পারে can তদ্ব্যতীত, প্রশ্নটি কি এটি ছিল তা নয়। আপনি কখনই কোনও লুকানো ইনপুট দিয়ে এই পরিস্থিতিতে প্রবেশ করতে পারবেন না এবং আমার উত্তরটি সবচেয়ে ভাল। Ya, <really>!
সুমেরে

3
/>এটি একটি এক্সএমএল-ইসম; এটি এইচটিএমএল এর কোনও সংস্করণে প্রয়োজন নেই, এক্সএইচটিএমএল ব্যতীত (যা সত্যই কখনও খুব বেশি ট্র্যাকশন অর্জন করতে পারেনি এবং এটি HTML5 দ্বারা ছাড়িয়ে গেছে)। এবং আপনি ঠিক বলেছেন যে সেখানে প্রচুর অগোছালো নয়-সত্যিকারের-বৈধ এইচটিএমএল রয়েছে তবে একটি ভাল এইচটিএমএল ( এক্সএমএল নয় ) পার্সারের বেশিরভাগ অংশটি সামলাতে সক্ষম হওয়া উচিত; যদি তা না করে তবে সম্ভবত ব্রাউজারগুলিও তা করবে না।
ইলমারি করোনেন

1
যদি আপনার কেবলমাত্র পার্সিং বা অনুসন্ধানের প্রয়োজন হয় তবে লুকানো ইনপুট ক্ষেত্রগুলির সংকলন ফেরত পেতে যদি একক হিট হয় তবে এই রেজেক্সটি সঠিক হবে। .NET এক্সএমএল ডকুমেন্ট ক্লাস (এস) ব্যবহার করে, বা রেইগেক্সটি অন্তর্নির্মিত হওয়ার পরে থ্রিম পার্টি এক্সএমএল / এইচটিএমএল পার্সারকে কেবল একটি পদ্ধতিতে কল করার জন্য অতিরিক্ত ব্যবহার করা হবে over এবং আপনি ঠিক বলেছেন যে কোনও ওয়েবসাইট এতটাই গণ্ডগোল করেছে যে একটি ভাল এইচটিএমএল পার্সার এটি পরিচালনা করতে পারেন সম্ভবত কোনও দেবের দিকে তাকিয়ে এমন কিছু নয়। তবে আমার সংস্থায় মাসে কয়েক মিলিয়ন পৃষ্ঠাগুলি হ্যান্ড-অফ হয়ে থাকে যা বিভিন্ন উপায়ে সংমিশ্রিত এবং জ্যাক করা হয় যে কখনও কখনও (সর্বদা নয়), রেজেক্স সেরা বিকল্প।
সুমেমে

1
কেবলমাত্র এটিই উল্লেখ করুন যে আমরা পুরো সংস্থার কারণ সম্পর্কে নিশ্চিত নই কারণ এই দেব এই উত্তরটি চান। তবে এটাই তিনি চেয়েছিলেন।
সুমেরে

3

আপনি এটি চেষ্টা করতে পারেন:

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

এবং কাছাকাছি ফলাফলের জন্য আপনি এটি চেষ্টা করতে পারেন:

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

আপনি এখানে আপনার রেজেক্স প্যাটার্নটি পরীক্ষা করতে পারেন http://regexpal.com/

এই প্যাটেনগুলি এটির জন্য ভাল:

<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**এইচটিএমএল কোডটি বের করতে ব্যবহার করতে চাই ।

$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') );
}

বিটিডাব্লু, আপনি এটি এখানে পরীক্ষা করতে পারবেন - regex101.com। এটি বাস্তব সময়ে ফলাফল দেখায়। Regexp সম্পর্কে কিছু নিয়ম: http://www.eclipse.org/tptp/home/downloads/installguide/gla_42/ref/rregexp.html পাঠক


0

ধরুন আপনার এইচটিএমএল বিষয়বস্তু স্ট্রিং এইচটিএমএলতে সঞ্চিত আছে তবে প্রতিটি ইনপুট যাতে ধরণের লুকানো থাকে তা পেতে আপনি নিয়মিত প্রকাশ করতে পারেন

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

উপরের রেজেক্সটি <inputঅক্ষরগুলির সংখ্যার পরে তা না পাওয়া পর্যন্ত এটি খুঁজে না পায় type="hidden"বা টাইপ করুন = 'লুকানো' এবং যতক্ষণ না অক্ষর পাওয়া যায় ততক্ষণ>

/ জি প্রদত্ত প্যাটার্নের সাথে মেলে এমন প্রতিটি স্ট্রিং খুঁজে পেতে নিয়মিত অভিব্যক্তি বলুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.