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




perl parsing (6)

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

एक उदाहरण:

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

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

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

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

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

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

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

धन्यवाद।


ऐसा लगता है कि आप वास्तव में HTML को पार्स करना चाहते हैं, मैं किसी भी अद्भुत संकुल को ऐसा करने की सलाह देता हूं:

या! आप निम्न में से किसी एक की तरह पार्सर का उपयोग कर सकते हैं:

  • PyParsing
  • DParser - अच्छा अजगर बाइंडिंग के साथ एक जीएलआर पार्सर।
  • एएनटीएलआर - एक पुनरावर्ती सभ्य पार्सर जनरेटर जो अजगर कोड उत्पन्न कर सकता है।

यह उदाहरण सुंदरसुप प्रलेखन से है :

from BeautifulSoup import BeautifulSoup, SoupStrainer
import re

links = SoupStrainer('a')
[tag for tag in BeautifulSoup(doc, parseOnlyThese=links)]
# [<a href="http://www.bob.com/">success</a>, 
#  <a href="http://www.bob.com/plasma">experiments</a>, 
#  <a href="http://www.boogabooga.net/">BoogaBooga</a>]

linksToBob = SoupStrainer('a', href=re.compile('bob.com/'))
[tag for tag in BeautifulSoup(doc, parseOnlyThese=linksToBob)]
# [<a href="http://www.bob.com/">success</a>, 
#  <a href="http://www.bob.com/plasma">experiments</a>]

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

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

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

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', '!']

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

हाथ-पार्सिंग एचटीएमएल बहुत ही ज़रूरी है और आप प्रीपेड एचटीएमएल पार्सर्स में से किसी एक का उपयोग करने में ज्यादा नहीं देंगे। यदि आपका 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";
    }

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

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, आदि के उपयोग से बच नहीं सकते हैं।)।


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

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 !

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





lex