python पर्ल या पायथन में कार्यक्षमता जैसे लेक्स का अनुकरण




perl parsing (7)

सीपीएएन पर निम्नलिखित मॉड्यूल के लिए दस्तावेज़ीकरण देखें

एचटीएमएल :: TreeBuilder

एचटीएमएल :: TableExtract

तथा

पार्स :: RecDescent

मैंने इन मॉड्यूलों को बहुत बड़े और जटिल वेब-पेजों पर कार्रवाई करने के लिए उपयोग किया है

यहाँ सौदा है। कई रेगेक्सस के आधार पर लाइन में स्ट्रिंग को चिन्हित करने का एक तरीका है?

एक उदाहरण:

मुझे सभी href टैग, उनके संबंधित टेक्स्ट और किसी अन्य रीजक्स पर आधारित कुछ अन्य पाठ प्राप्त करना होगा। इसलिए मेरे पास 3 भाव हैं और लाइन को टोकने के लिए और हर अभिव्यक्ति से मेल खाने वाले टेक्स्ट के टोकन निकालना चाहते हैं।

मैंने वास्तव में यह फ्लेक्स (एडीए के साथ भ्रमित नहीं होना) का उपयोग किया है, जो अच्छे पुराने लेक्स के कार्यान्वयन है। लेक्स अभिव्यक्ति के आधार पर "कार्यों" निष्पादित करके ऐसा करने का एक शानदार तरीका प्रदान करता है। कोई भी लेक्स को फाइल पढ़ने के तरीके को नियंत्रित कर सकता है (ब्लॉक / लाइन आधारित पठन)।

समस्या यह है कि फ्लेक्स वास्तव में C / C ++ कोड उत्पन्न करता है जो वास्तव में टोकनिंग नौकरी करता है। मेरे पास एक मेक फाइल है जो इन सभी चीजों को लपेटता है मैं सोच रहा था कि क्या पर्ल / अजगर कुछ तरह से एक ही काम करते हैं इसका सिर्फ इतना है कि मैं एक प्रोग्रामिंग भाषा में स्वयं को सब कुछ पसंद करूंगा।

टोकनिंग केवल उन चीजों में से एक है जो मैं अपने आवेदन के हिस्से के रूप में करना चाहता हूं।

पर्ल या अजगर के अलावा कोई भी भाषा (कार्यात्मक भी) कर सकती है?

मैंने PLY और एएनटीएलआर के बारे में यहां पढ़ा था ( पार्सिंग, मैं इसके बारे में कहां सीख सकता हूँ )

लेकिन क्या अजगर में स्वाभाविक रूप से ऐसा करने का एक तरीका है? मेरी अज्ञानता को क्षमा करें, लेकिन क्या ये उपकरण किसी भी लोकप्रिय उत्पादों / सेवाओं में उपयोग किए जाते हैं?

धन्यवाद।


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

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


प्रतिलिपि से :

लेक्स के /\G.../gc स्कैनर के लिए एक उपयोगी /\G.../gc है / / /\G.../gc आप इस तरह से कई regexps को एक स्ट्रिंग भाग-बाय-पार्ट की प्रक्रिया के लिए जोड़ सकते हैं, जिस पर regexp मिलान के आधार पर अलग-अलग क्रिया कर रहे हैं। प्रत्येक regexp मैच की कोशिश करता है, जहां पिछले एक छोड़ देता है।

 LOOP:
    {
      print(" digits"),       redo LOOP if /\G\d+\b[,.;]?\s*/gc;
      print(" lowercase"),    redo LOOP if /\G[a-z]+\b[,.;]?\s*/gc;
      print(" UPPERCASE"),    redo LOOP if /\G[A-Z]+\b[,.;]?\s*/gc;
      print(" Capitalized"),  redo LOOP if /\G[A-Z][a-z]+\b[,.;]?\s*/gc;
      print(" MiXeD"),        redo LOOP if /\G[A-Za-z]+\b[,.;]?\s*/gc;
      print(" alphanumeric"), redo LOOP if /\G[A-Za-z0-9]+\b[,.;]?\s*/gc;
      print(" line-noise"),   redo LOOP if /\G[^A-Za-z0-9]+/gc;
      print ". That's all!\n";
    }

पीजीटी को भी इस प्रकार की सामग्री बनाने का एक बहुत अच्छा पर्लिश तरीका के रूप में देखें।

use pQuery;

pQuery( 'http://www.perl.com' )->find( 'a' )->each( 
    sub {
        my $pQ = pQuery( $_ ); 
        say $pQ->text, ' -> ', $pQ->toHtml;
    }
);

# prints all HTML anchors on www.perl.com
# =>  link text -> anchor HTML

हालांकि यदि आपकी आवश्यकता एचटीएमएल / वेब से परे है तो यह पहले "हैलो वर्ल्ड!" है उदाहरण पार्स :: रिक डेनिसेंट में ...

use strict;
use warnings;
use Parse::RecDescent;

my $grammar = q{
    alpha : /\w+/
    sep   : /,|\s/
    end   : '!'
    greet : alpha sep alpha end { shift @item; return \@item }
};

my $parse = Parse::RecDescent->new( $grammar );
my $hello = "Hello, World!";
print "$hello -> @{ $parse->greet( $hello ) }";

# => Hello, World! -> Hello , World !

शायद इस अखरोट को दरकिनार करने के लिए एक बड़ा हथौड़ा के बहुत अधिक ;-)


क्या आपने पायपार्सिंग को देखा है?

अपने मुखपृष्ठ से:

यहां "हैलो, वर्ल्ड!" को पार्स करने वाला एक कार्यक्रम है (या फॉर्म के किसी भी शुभकामना ",!"):

from pyparsing import Word, alphas
greet = Word( alphas ) + "," + Word( alphas ) + "!" # <-- grammar defined here
hello = "Hello, World!"
print hello, "->", greet.parseString( hello )

कार्यक्रम निम्नलिखित को आउटपुट करता है:

Hello, World! -> ['Hello', ',', 'World', '!']

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

#!/usr/bin/perl
use strict;
use warnings;
use WWW::Mechanize;

my $mech = WWW::Mechanize->new;

$mech->get("http://.com/");

$mech->success or die "Oh no! Couldn't fetch .com";

foreach my $link ($mech->links) {
    print "* [",$link->text, "] points to ", $link->url, "\n";
}

मुख्य पाश में, प्रत्येक $link एक WWW :: Mechanize :: लिंक ऑब्जेक्ट है, इसलिए आप पाठ और URL प्राप्त करने के लिए अभी सीमित नहीं हैं

शुभकामनाएं,

पॉल


ब्रूनो के उदाहरण को संशोधित करने के लिए त्रुटि जांच शामिल है:

my $input = "...";
while (1) {
    if ($input =~ /\G(\w+)/gc) { print "word: '$1'\n"; next }
    if ($input =~ /\G(\s+)/gc) { print "whitespace: '$1'\n"; next }

    if ($input !~ /\G\z/gc)  { print "tokenizing error at character " . pos($input) . "\n" }
    print "done!\n"; last;
}

(ध्यान दें कि स्केलर // जी का उपयोग दुर्भाग्यवश एक जगह है जहां आप वास्तव में $ 1, आदि के उपयोग से बच नहीं सकते हैं।)।





lex