题
这里的交易。有没有办法有串的标记在线基础上的多regex?
一个例子:
我必须得到所有href标签,他们相应的文本和其他一些文本,根据不同的regex.所以我有3个表情和愿标记线和提取记号的文字匹配的每一个的表达。
其实我已经这样做使用flex(不要混淆Adobe),这是一个实现良好的老莱克斯莱克提供了 优雅的方式做到这一通过执行"行动"的基础上的表情。一个可以控制的方式 莱克斯的阅读一个文件(框/行基于读)。
问题是,flex实际上产生C/C++的代码实际上没有标记化的工作。我有一个 作文件,该文件包所有这些事情。我想知道,如果perl/蟒蛇可以在一些方式做同样的事情。它只是说我想做的一切 我喜欢在一个单一的编程语言本身。
切分为只有一个东西,我想要做的一部分,我的应用程序。
除了perl或蟒蛇可以以任何语言(功能还)这样做吗?
我没有阅读有关的帘布层和这些代码在这里(分析,我在哪里可以学习它).
但是有一个办法做到这一自然蟒蛇本身?请原谅我的无知,但是这些工具用于任何受欢迎的产品/服务?
谢谢你。
解决方案
如果你是在解析网页链接之后,那么Perl的 WWW: :Mechanize 模块将以非常优雅的方式为您解决问题。这是一个示例程序,它抓取Stack Overflow的第一页并解析所有链接,打印其文本和相应的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 :: Mechanize :: Link 对象,因此您不仅限于获取文本和URL。
一切顺利,
保
其他提示
听起来像你真的只是要分析HTML,我建议在任何美好的软件包为这样做:
或!你可以使用一个分析器喜欢下列之一:
这个例子是从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 吗?
从他们的主页:
这是一个解析“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', '!']
如果您的问题与网页抓取有任何关系,我建议您查看网页:: Scraper ,通过XPath和CSS选择器提供简单的元素选择。我有一个(德语)在Web上讨论:: Scraper ,但如果您通过babelfish运行它或只是查看代码示例,这可以帮助您快速了解语法。
手工解析HTML是繁重的,并且不会过多地使用其中一个预制的HTML解析器。如果您的HTML变化非常有限,那么您可以使用聪明的正则表达式,但是如果您已经打破了核心解析器工具,那么听起来好像您的HTML比解析的更加合理。正则表达式。
来自 perlop :
类似于lex的扫描仪的有用习惯用法 是
/ \ G ... / gc
。你可以结合起来 像这样的几个regexp来处理a 逐个字符串,做不同的 行动取决于哪个正则表达式 匹配。每个正则表达式都尝试匹配 前一个离开的地方。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( 另请查看 pQuery ,这是一种非常好的Perlish方式东西....
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 !
但是,如果您的要求超出HTML / Web,那么这里是早期的“Hello World!”。例如 Parse :: RecDescent ...
<*>
可能用太大的锤子来破解这个坚果; - )
);
say $pQ->text, ' -> ', $pQ->toHtml;
}
);
# prints all HTML anchors on www.perl.com
# => link text -> anchor HTML
但是,如果您的要求超出HTML / Web,那么这里是早期的“Hello World!”。例如 Parse :: RecDescent ...
<*>可能用太大的锤子来破解这个坚果; - )
修改Bruno的示例以包含错误检查:
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;
}
(请注意,使用标量// g很遗憾,您无法避免使用$ 1等变量。)