سؤال

هنا الصفقة.هل هناك طريقة لجعل سلاسل tokenized في خط بناء على عدة regexes?

مثال واحد:

يجب أن تحصل على كل href العلامات ، يقابلها من النص و بعض النصوص الأخرى على أساس مختلف regex.لذلك لدي 3 تعابير مثل tokenize الخط و استخراج الرموز من مطابقة النص كل تعبير.

لقد فعلت هذا الواقع باستخدام فليكس (وينبغي عدم الخلط مع أدوبي) الذي هو تنفيذ القديمة الجيدة ليكس.ليكس يوفر أنيقة طريقة للقيام بذلك عن طريق تنفيذ "الأعمال" على أساس التعبير.يمكن للمرء أن السيطرة على الطريق ليكس قراءة الملف أيضا (كتلة / خط أساس قراءة).

المشكلة هي أن فليكس ينتج في الواقع C/ C++ code والتي في الواقع لا tokenizing العمل.لدي جعل الملف الذي يلف كل هذه الأمور.كنت أتساءل إذا perl /python يمكن في بعض الطريق تفعل الشيء نفسه.فقط أود أن تفعل كل شيء أنا أحب واحد لغة البرمجة نفسها.

Tokenizing هو مجرد واحدة من الأشياء التي أريد القيام به كجزء من التطبيق.

وبصرف النظر عن بيرل أو بايثون يمكن أي لغة (وظيفية أيضا) فعل هذا ؟

لقد قرأت عن رقائق و ANTLR هنا (تحليل أين يمكنني معرفة المزيد عن ذلك).

ولكن هل هناك طريقة للقيام بذلك بشكل طبيعي في بيثون نفسها ؟ العفو جهلي ولكن هذه الأدوات المستخدمة في أي شعبية المنتجات / الخدمات ؟

شكرا لك.

هل كانت مفيدة؟

المحلول

إذا كنت على وجه التحديد بعد تحليل الروابط من صفحات الويب، ثم WWW: : يمكنن حدة ومعرفة الأمور بالنسبة لك بطريقة أنيقة جدا. وفيما يلي نموذج البرنامج أن الاستيلاء على الصفحة الأولى من تجاوز المكدس ويوزع من جميع الروابط، طباعة النص وعناوين URL المقابلة:

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

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

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

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

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

في حلقة رئيسية، كل $link هو WWW :: :: يمكنن كائن ارتباط ، لذلك كنت لا يحد فقط إلى الحصول على النص وURL.

وكل خير،

وبول

نصائح أخرى

ونظرة على وثائق لمتابعة وحدات على CPAN

HTML :: TreeBuilder

HTML :: TableExtract

و

تحليل :: RecDescent

ولقد استعملت هذه الوحدات لمعالجة صفحات الويب كبيرة جدا ومعقدة.

يبدو أنك حقا تريد فقط تحليل HTML, أوصي النظر في أي من باقات خدمات رائعة للقيام بذلك:

أو!يمكنك استخدام محلل مثل أحد الإجراءات التالية:

  • PyParsing
  • DParser - أ GLR محلل مع بيثون الارتباطات.
  • ANTLR - عودي الكريم محلل مولد التي يمكن أن تولد كود بايثون.

هذا المثال هو من BeautifulSoup الوثائق:

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>]

هل نظرت إلى PyParsing ؟

ومن الصفحة الرئيسية الخاصة بهم:

وهنا هو برنامج لتحليل "مرحبا، العالم!" (أو أي تحية من النموذج "،!"):

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

إذا كان لديك مشكلة لديه أي شيء على الإطلاق للقيام مع ويب كشط, أوصي تبحث في ويب::مكشطة الذي يوفر سهولة اختيار عنصر عبر XPath على التوالي محددات CSS.لدي (الألمانية) التحدث على شبكة الإنترنت::مكشطة ولكن إذا قمت بتشغيل من خلال بابيل فيش أو مجرد إلقاء نظرة على نماذج التعليمات البرمجية التي يمكن أن تساعدك على الحصول على لمحة سريعة عن الجملة.

من ناحية تحليل HTML هي مرهقة لن تعطيك أكثر باستخدام إحدى ولم يضف HTML موزعي.إذا HTML الخاص بك هو محدود جدا الاختلاف ، يمكنك الحصول عليه من خلال استخدام ذكي التعابير العادية ، ولكن إذا كنت بالفعل الخروج صلب محلل أدوات يبدو كما لو HTML الخاص بك هو أكثر بكثير من عادية ما هو عاقل تحليل مع التعبيرات العادية.

perlop :

<اقتباس فقرة>   

وهناك لغة مفيدة لالماسحات الضوئية تشبه ليكس   غير /\G.../gc. يمكنك الجمع بين   عدة regexps مثل هذا لمعالجة ل   سلسلة لجزء من كل جزء، والقيام مختلفة   الإجراءات اعتمادا على التعبير العادي   يقابل. يحاول كل التعبير العادي لمطابقة   حيث سابقتها يترك خارج.

 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";
    }

وكما تحقق pQuery أنها وسيلة Perlish لطيف من القيام بهذا النوع من الاشياء ....

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

ولكن إذا الشرط الخاص بك هو أبعد HTML / الانترنت ثم هنا هو سابق "مرحبا العالم!" مثلا في تحليل :: RecDescent ...

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 !

وربما الكثير من مطرقة كبيرة للقضاء هذا الجوز، -)

مثال

والتعديل برونو لتشمل التحقق من الخطأ:

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 $، الخ المتغيرات).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top