0

タグ内のデータを抽出するために perl で SimpleXml を使用します

<description>&lt;strong&gt;CUSIP:&lt;/strong&gt; 912828UC2&lt;br /&gt;&lt;strong&gt;Term and Type:&lt;/strong&gt; 3-Year Note&lt;br /&gt;&lt;strong&gt;Offering Amount:&lt;/strong&gt; $32,000,000,000&lt;br /&gt;&lt;strong&gt;Auction Date:&lt;/strong&gt; 12/11/2012&lt;br /&gt;&lt;strong&gt;Issue Date:&lt;/strong&gt; 12/17/2012&lt;br /&gt;&lt;strong&gt;Maturity Date:&lt;/strong&gt; 12/15/2015&lt;br /&gt;&lt;a href="http://www.treasurydirect.gov/instit/annceresult/press/preanre/2012/A_20121206_6.pdf"&gt;PDF version of the announcement&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.treasurydirect.gov/xml/A_20121206_6.xml"&gt;XML version of the announcement&lt;/a&gt;&lt;br /&gt;</description>

個々のシンボルを抽出するのに問題があります。たとえば、オークションの日付には、

if ($desc=~m/Auction\sDate:<\/strong>\s+(\d\d\/\d\d\/\d\d\d\d)<br/) {

}

しかし、私はそれが十分に堅牢ではないと感じています。フィールドを抽出する標準的な方法は何ですか?

4

3 に答える 3

2

Dan1111 が彼の回答で指摘しているように、既に XML パーサー (Simple::XML?) を使用している場合は、説明タグ内のデータを解析するためにそれを使い続ける必要があります。XML/HTML フィードからデータを解析しようとするのは得策ではありません。その目的のために構築されたパーサーを使用します。

あなたの投稿のデータのフォーマットが原因で、パーサーが役立つ有効な HTML を持っていないと思います。この場合、フィールドを抽出する「標準的な」方法はありませんが、私がこの問題に取り組む方法は次のとおりです。

print "$desc\n";

my @parts = split(/;br /, $desc);
my %dates;

foreach my $part (@parts) {
  if ($part =~ m/(\w+\s+Date).+(\d{2}\/\d{2}\/\d{4})/) {
    $dates{$1} = $2;
  }
}

foreach my $label (keys %dates) {
  printf "%-16s%12s\n", "${label}:", $dates{$label};
}

元の文字列を見ると、3 つの日付と、他にもいくつかのレコードがあることがわかります。最初に行うことは、splitそれらをアップすることです。文字列内の各レコードが文字「;br」で区切られていることがわかったので、それを分割に使用しました。

my @parts = split(/;br /, $desc);

それを行った後、文字列のさまざまなデータ部分をそれぞれ含む配列ができました。今、私は各部分を解析する必要がありました。あなたの質問はオークションの日付の値に興味があるので、日付を取得する正規表現を書きました。他の日付も同様に価値があると予想して、ラベル (オークション、発行、成熟度) を取得できるように正規表現を変更し、ラベルと日付の各ペアをハッシュ (%dates) に保存しました。

foreach my $part (@parts) {
  if ($part =~ m/(\w+\s+Date).+(\d{2}\/\d{2}\/\d{4})/) {
    $dates{$1} = $2;
  }
}

最後に、ハッシュを印刷しました。

foreach my $part (@parts) {
  if ($part =~ m/(\w+\s+Date).+(\d{2}\/\d{2}\/\d{4})/) {
    $dates{$1} = $2;
  }
}  

わかる?

于 2012-12-12T14:34:51.717 に答える
0

より堅牢なものは、予想される入力と探しているものによって異なります。ただし、ここに役立つものがあります。

これに使いXML::Twigました。 XML::Simple(あなたが現在使用しているものと思います)は、さまざまな癖があるため、新しい開発にはお勧めできません。

use Modern::Perl;
use XML::Twig;

my $twig = XML::Twig->new();
$twig->parse(<DATA>);

my %params;
my $key;
for my $child (map {$_->text} $twig->root->children)
{
    if ($child =~ /(.*):/)
    {
        $key = $1;  
    }
    else
    {
        $params{$key} = $child if (defined $key);
        undef $key;         
    }
}

say "$_ is $params{$_}" foreach (keys %params); 

__DATA__
<description><strong>CUSIP:</strong> 912828UC2<br /><strong>Term and Type:</strong> 3-Year Note<br /><strong>Offering Amount:</strong> $32,000,000,000<br /><strong>Auction Date:</strong> 12/11/2012<br /><strong>Issue Date:</strong> 12/17/2012<br /><strong>Maturity Date:</strong> 12/15/2015<br /><a href="http://www.treasurydirect.gov/instit/annceresult/press/preanre/2012/A_20121206_6.pdf">PDF version of the announcement</a><br /><a href="http://www.treasurydirect.gov/xml/A_20121206_6.xml">XML version of the announcement</a><br /></description>

これは、コロンで終わる要素をキーとして取り、ツリー内の次の要素が値であると想定します。明らかに、どのような種類の入力が得られるかについていくつかの仮定が行われますが、すべての「キー」要素がタグで囲まれている限り、かなり堅牢です。

もう 1 つの方法は、最初にすべてのタグを削除してから、テキストだけでキーと値のペアを検索することです。XML::Twigこれも同様に行うことができます。単純に呼び出す$twig->root->textと、要素全体からテキストが取得されます。ただし、このアプローチでは、あるキーがどこで終わり、別の値が始まるかを判断するのは難しいでしょう。

于 2012-12-12T14:39:54.893 に答える
0

表示する RSS フィードの<description>要素には、有効な XHTML フラグメントが PCDATA として含まれています。このソリューションは、これらの要素を抽出してデコードし、順に解析して、<strong>要素のテキストとそれに対応する値にアクセスします。

XHTML には複数の要素が含まれていることに注意してください。XHTML では単一のルート要素しか許可されていないため<root>$twig->parse("<root>$desc</root>").

これから推定して、必要なデータにアクセスできることを願っています。

use strict;
use warnings;

use LWP::Simple;
use XML::Twig;

my $xml = get 'http://www.treasurydirect.gov/RI/TreasuryOfferingAnnouncements.rss';

my $twig = XML::Twig->new;
$twig->parse($xml);

for my $desc ($twig->get_xpath('/rss/channel/item/description')) {
  $desc = $desc->text;
  my $twig = XML::Twig->new;
  $twig->parse("<root>$desc</root>");
  for my $strong ($twig->get_xpath('/root/strong')) {
    my ($key, $val) = ($strong->trimmed_text, $strong->next_sibling->trimmed_text);
    $key =~ s/:$//;
    print "$key => $val\n";
  }
  print "\n";
}

出力

CUSIP -> 912810QY7
Term and Type -> 29-Year 11-Month Bond
Offering Amount -> $13,000,000,000
Auction Date -> 12/13/2012
Issue Date -> 12/17/2012
Maturity Date -> 11/15/2042

CUSIP -> 912796DT3
Term and Type -> 3-Day Bill
Offering Amount -> $10,000,000,000
Auction Date -> 12/13/2012
Issue Date -> 12/14/2012
Maturity Date -> 12/17/2012

CUSIP -> 912828UE8
Term and Type -> 5-Year Note
Offering Amount -> $35,000,000,000
Auction Date -> 12/18/2012
Issue Date -> 12/31/2012
Maturity Date -> 12/31/2017

CUSIP -> 912828UD0
Term and Type -> 2-Year Note
Offering Amount -> $35,000,000,000
Auction Date -> 12/17/2012
Issue Date -> 12/31/2012
Maturity Date -> 12/31/2014

CUSIP -> 912796AM1
Term and Type -> 26-Week Bill
Offering Amount -> $28,000,000,000
Auction Date -> 12/17/2012
Issue Date -> 12/20/2012
Maturity Date -> 06/20/2013

CUSIP -> 912828UF5
Term and Type -> 7-Year Note
Offering Amount -> $29,000,000,000
Auction Date -> 12/19/2012
Issue Date -> 12/31/2012
Maturity Date -> 12/31/2019

CUSIP -> 912828SQ4
Term and Type -> 4-Year 4-Month TIPS
Offering Amount -> $14,000,000,000
Auction Date -> 12/20/2012
Issue Date -> 12/31/2012
Maturity Date -> 04/15/2017

CUSIP -> 9127957M7
Term and Type -> 13-Week Bill
Offering Amount -> $32,000,000,000
Auction Date -> 12/17/2012
Issue Date -> 12/20/2012
Maturity Date -> 03/21/2013

CUSIP -> 912828TY6
Term and Type -> 9-Year 11-Month Note
Offering Amount -> $21,000,000,000
Auction Date -> 12/12/2012
Issue Date -> 12/17/2012
Maturity Date -> 11/15/2022

CUSIP -> 912828UC2
Term and Type -> 3-Year Note
Offering Amount -> $32,000,000,000
Auction Date -> 12/11/2012
Issue Date -> 12/17/2012
Maturity Date -> 12/15/2015

CUSIP -> 912796AK5
Term and Type -> 52-Week Bill
Offering Amount -> $25,000,000,000
Auction Date -> 12/11/2012
Issue Date -> 12/13/2012
Maturity Date -> 12/12/2013

CUSIP -> 9127955V9
Term and Type -> 4-Week Bill
Offering Amount -> $40,000,000,000
Auction Date -> 12/11/2012
Issue Date -> 12/13/2012
Maturity Date -> 01/10/2013

CUSIP -> 912796AL3
Term and Type -> 26-Week Bill
Offering Amount -> $28,000,000,000
Auction Date -> 12/10/2012
Issue Date -> 12/13/2012
Maturity Date -> 06/13/2013

CUSIP -> 9127957L9
Term and Type -> 13-Week Bill
Offering Amount -> $32,000,000,000
Auction Date -> 12/10/2012
Issue Date -> 12/13/2012
Maturity Date -> 03/14/2013

CUSIP -> 912796DT3
Term and Type -> 11-Day Bill
Offering Amount -> $25,000,000,000
Auction Date -> 12/04/2012
Issue Date -> 12/06/2012
Maturity Date -> 12/17/2012

CUSIP -> 9127956Z9
Term and Type -> 4-Week Bill
Offering Amount -> $40,000,000,000
Auction Date -> 12/04/2012
Issue Date -> 12/06/2012
Maturity Date -> 01/03/2013
于 2012-12-15T04:24:19.583 に答える