I've got the Amazon API, it works fine. But the output is alway from the US store (amazon.com) but I would like to have it from the UK store (amazon.co.uk) how should I do this?
$AWSAccessKeyId = "KEYID";
$SecretAccessKey = "ACCESKEY";
$ItemId = "12345"; // ASIN and ISBN10 or ISBN13
if(strlen($ItemId)>=13){
$ItemId = isbn13to10($ItemId);
}
$Timestamp = gmdate("Y-m-d\TH:i:s\Z");
$Timestamp = str_replace(":", "%3A", $Timestamp);
$ResponseGroup = "ItemAttributes,Offers,Images,Reviews";
$ResponseGroup = str_replace(",", "%2C", $ResponseGroup);
$String = "AWSAccessKeyId=$AWSAccessKeyId&AssociateTag=notUsed&";
$String .= "ItemId=$ItemId&
Operation=ItemLookup&
ResponseGroup=Offers&
Service=AWSECommerceService&";
$String .= "Timestamp=$Timestamp&
Version=2009-01-06";
$String = str_replace("\n", "", $String);
$Prepend = "GET\nwebservices.amazon.com\n/onca/xml\n";
$PrependString = $Prepend . $String;
$Signature = base64_encode(hash_hmac("sha256", $PrependString, $SecretAccessKey, True));
$Signature = str_replace("+", "%2B", $Signature);
$Signature = str_replace("=", "%3D", $Signature);
$BaseUrl = "http://webservices.amazon.com/onca/xml?";
$SignedRequest = $BaseUrl . $String . "&Signature=" . $Signature;
$XML = simplexml_load_file($SignedRequest);
Ahh, that was easy... So easy that one wouldn't expect it...
$Prepend = "GET\nwebservices.amazon.co.uk\n/onca/xml\n";
$BaseUrl = "http://webservices.amazon.co.uk/onca/xml?";
Related
How can I substitute only in matched pattern and put it back in same variable using Perl?
For example:
my $str = "a.b.AA pat1 BB hgf AA pat1 BB jkl CC pat1 don't change pat1";
I want to match pat1 between AA and BB and replace it with Original string PAT2. However, I don't want to replace pat1 anywhere else in the same string
Expected output string:
a.b.AA PAT2 BB hgf AA PAT2 BB jkl CC pat1 don't change pat1
I am sure there should be some good way to do it; please advise.
Original string:
my $ORG_str = 'A.B.C.\\valid.A .\\valid.A.B.C .\\valid.X.Y.Z .p.q.r.s';
Expected String:
my $EXP_op = 'A.B.C.\\valid?A .\\valid?A?B?C .\\valid?X?Y?Z .p.q.r.s';
Substitute character . to ? only if it is between backslash \ and whitespace .
Look into look-around regexes.
s/(?<=AA )pat1(?= BB)/pat2/g
This matches and replaces a pat1 surrounded by AA and BB.
Not very simple with one single regexp, so I used divide and conquer to compute the result. This is a small recursive function that is replacing a single '.' per group of ('\' ' ')
The iteration ends when there is nothing to replace
sub replace {
my ($input) = #_;
my $result = $input;
$result =~ s/(\\\S*?)\.(.*? )/$1?$2/g;
return $result if $result eq $input;
return replace($result);
}
The function with some test cases
use strict;
my $ORG_str= 'A.B.C.\\\\valid.A .\\\\valid.A.B.C .\\\\valid.X.Y.Z .p.q.r.s';
my $EXP_op ='A.B.C.\\\\valid?A .\\\\valid?A?B?C .\\\\valid?X?Y?Z .p.q.r.s';
sub replace {
my ($input) = #_;
my $result = $input;
$result =~ s/(\\\S*?)\.(.*? )/$1?$2/g;
return $result if $result eq $input;
return replace($result);
}
my $check;
my $result;
my $expected;
$check = 'abcd'; $expected = $check;
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = 'ab\xxx. cd'; $expected = 'ab\xxx? cd';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = 'ab\x.x.x. cd'; $expected = 'ab\x?x?x? cd';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = 'ab\x.x.x. cd\y.y.y.'; $expected = 'ab\x?x?x? cd\y.y.y.';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = 'ab\x.x.x. cd\xxx.xxx..xxx...x \y.y.y.'; $expected = 'ab\x?x?x? cd\xxx?xxx??xxx???x \y.y.y.';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = '. ..\.. ...\.. ...\.. ...\..'; $expected = '. ..\?? ...\?? ...\?? ...\..';
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
$check = $ORG_str; $expected = $EXP_op;
$result = replace($check);
assert($result eq $expected, "'$check' gives '$expected'");
sub assert {
my ($cond, $mesg) = #_;
print "checking $mesg ... ";
die "\nFAIL: $mesg" unless $cond;
print "OK\n";
}
The result
checking 'abcd' gives 'abcd' ... OK
checking 'ab\xxx. cd' gives 'ab\xxx? cd' ... OK
checking 'ab\x.x.x. cd' gives 'ab\x?x?x? cd' ... OK
checking 'ab\x.x.x. cd\y.y.y.' gives 'ab\x?x?x? cd\y.y.y.' ... OK
checking 'ab\x.x.x. cd\xxx.xxx..xxx...x \y.y.y.' gives 'ab\x?x?x? cd\xxx?xxx??xxx???x \y.y.y.' ... OK
checking '. ..\.. ...\.. ...\.. ...\..' gives '. ..\?? ...\?? ...\?? ...\..' ... OK
checking 'A.B.C.\\valid.A .\\valid.A.B.C .\\valid.X.Y.Z .p.q.r.s' gives 'A.B.C.\\valid?A .\\valid?A?B?C .\\valid?X?Y?Z .p.q.r.s' ... OK
\\\\[^. ]*\K|(?!^)\G\.([^. ]*)
You can try this.Replace by ?$1.See demo.
https://regex101.com/r/mT0iE7/28
The resultant string will not be exactly same as you want but you can easily do a clean up.
\?(?=\?)
Replace by empty string and you have what you want.See demo.
https://regex101.com/r/mT0iE7/29
I would like to remove all addresses that start with '192.18' from results. I keep either removing all addresses or none...
Here is the code.
sub get_oids{
my($starting_oid , $new_oid , $unique_oid , $result , $crap);
my($ip , $name , $port , $type);
$starting_oid = $_[0];
$new_oid = $starting_oid ;
while(Net::SNMP::oid_context_match($starting_oid,$new_oid)){
$result = $session->get_next_request(($new_oid));
return unless (defined $result);
($new_oid , $crap) = %$result;
if (Net::SNMP::oid_context_match($starting_oid,$new_oid)){
$unique_oid = $new_oid;
$unique_oid =~ s/$starting_oid//g;
$ip = (Convert_IP(Get_SNMP_Info("$oid_root".".4"."$unique_
+oid")));
$name = (Get_SNMP_Info("$oid_root".".6"."$unique_oid"));
$port = (Get_SNMP_Info("$oid_root".".7"."$unique_oid"));
$type = (Get_SNMP_Info("$oid_root".".8"."$unique_oid"));
#todo=(#todo,$ip);
write;
get_oids($new_oid);
Have you considered using the contains() method from NetAddr::IP?
#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use NetAddr::IP;
my #ips = qw(192.168.0.1 192.18.0.1 192.18.22.44 255.255.255.0);
my $Range = NetAddr::IP->new('192.18.0.0/16');
for my $ip (#ips) {
my $IP = NetAddr::IP->new($ip);
my $contains = $Range->contains($IP) ? "yes" : "no";
say "$ip: $contains";
}
Which gives the following output:
alex#yuzu:~$ ./net_addr_ip.pl
192.168.0.1: no
192.18.0.1: yes
192.18.22.244: yes
255.255.255.0: no
This is nuts, I mean pseudocode, but something like this:
/[January, February, March] \d*/
Should match things like January 13 or February 26, and so on...
WHAT I'M DOING:
my $url0 = 'http://www.registrar.ucla.edu/calendar/acadcal13.htm';
my $url1 = 'http://www.registrar.ucla.edu/calendar/acadcal14.htm';
my $url2 = 'http://www.registrar.ucla.edu/calendar/acadcal15.htm';
my $url3 = 'http://www.registrar.ucla.edu/calendar/acadcal16.htm';
my $url4 = 'http://www.registrar.ucla.edu/calendar/acadcal17.htm';
my $url5 = 'http://www.registrar.ucla.edu/calendar/sumcal.htm';
my $document0 = get($url0);
my $document1 = get($url1);
my $document2 = get($url2);
my $document3 = get($url3);
my $document4 = get($url4);
my $document5 = get($url5);
my #dates0 = ($document0 =~ /(January|February|March|April|May|June|July|August|September|October|November|December) \d+/g);
my #dates1 = ($document1 =~ /(January|February|March|April|May|June|July|August|September|October|November|December) \d+/g);
my #dates2 = ($document2 =~ /(January|February|March|April|May|June|July|August|September|October|November|December) \d+/g);
my #dates3 = ($document3 =~ /(January|February|March|April|May|June|July|August|September|October|November|December) \d+/g);
my #dates4 = ($document4 =~ /(January|February|March|April|May|June|July|August|September|October|November|December) \d+/g);
my #dates5 = ($document5 =~ /(January|February|March|April|May|June|July|August|September|October|November|December) \d+/g);
foreach(#dates0)
{
print "$_\r\n";
}
foreach(#dates1)
{
print "$_\r\n";
}
foreach(#dates2)
{
print "$_\r\n";
}
foreach(#dates3)
{
print "$_\r\n";
}
foreach(#dates4)
{
print "$_\r\n";
}
foreach(#dates5)
{
print "$_\r\n";
}
These printing gadgets give the following result: http://pastebin.com/7z13gBqt
This is not good:
http://tinypic.com/r/nqpapx/8
Yes. You can use an alternation.
/(January|February|March|April|May|June|July|August|September|October|November|December) \d*/
Would do that.
If you already have them in an array, then you can change the variable $LIST_SEPARATOR to string them into an alternation. And then parenthesize the whole
use English qw<$LIST_SEPARATOR>; # In line-noise: $"
my $date_regex
= do { local $LIST_SEPARATOR = '|';
qr/(?:#months) \d*/ # ?: if you don't want the capture
};
This gives you a compiled expression, which you can reuse like so:
my #dates;
while ( my $url = <DATA> ) {
my $document = get( $url );
push #dates, [ $document =~ /($date_regex)/g ];
push #dates, $date;
}
__DATA__
http://www.registrar.ucla.edu/calendar/acadcal13.htm
http://www.registrar.ucla.edu/calendar/acadcal14.htm
http://www.registrar.ucla.edu/calendar/acadcal15.htm
http://www.registrar.ucla.edu/calendar/acadcal16.htm
http://www.registrar.ucla.edu/calendar/acadcal17.htm
http://www.registrar.ucla.edu/calendar/sumcal.htm
Say, I have lines like:
SOMETHING.AA.AA.DARKSIDE
BLaH.AA.AA.Blah
I want to find for each line $before = $1; $after = $2; of the $middle = ”AA”
Such that for example for line 1 I get:
$before= “SOMETHING.”
$After = “.AA.DARKSIDE”
And also
$before= “SOMETHING.AA”
$After = “.DARKSIDE”
My code looks like this:
$middle = “AA”;
foreach (#lines){
$line = $_;
while ($line =~m/^(.+)$middle(.+)$/g){
$before = $1;
$after = $2;
}
}
Is there a simple way to change regex in my while?
PS: $middle will be a variable so i cannot hardcode it.
Thank you for help.
Why do you want to use regexes for that?
($before, $after) = split(/$middle\.$middle/, $line);
And then use $before and $after each once without and once with $middle concatenated to the end and start of the string respectively.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How can I split a string into chunks of two characters each in Perl?
I wanted to split a string into an array grouping it by 2-character pieces:
$input = "DEADBEEF";
#output = split(/(..)/,$input);
This approach produces every other element empty.
$VAR1 = '';
$VAR2 = 'DE';
$VAR3 = '';
$VAR4 = 'AD';
$VAR5 = '';
$VAR6 = 'BE';
$VAR7 = '';
$VAR8 = 'EF';
How to get a continuous array?
$VAR1 = 'DE';
$VAR2 = 'AD';
$VAR3 = 'BE';
$VAR4 = 'EF';
(...other than getting the first result and removing every other row...)
you can easily filter out the empty entries with:
#output = grep { /.+/ } #output ;
Edit:
You can obtain the same thing easier:
$input = "DEADBEEF";
my #output = ( $input =~ m/.{2}/g );
Edit 2 another version:
$input = "DEADBEEF";
my #output = unpack("(A2)*", $input);
Regards
Try this:
$input = "DEADBEEF";
#output = ();
while ($input =~ /(.{2})/g) {
push #output, $1;
}