Re: sequential substitutions
by haukex (Archbishop) on Aug 03, 2018 at 10:01 UTC
|
use warnings;
use strict;
use Mojo::DOM;
my $xml = <<'ENDXML';
<foo>3</foo>
<foo>14</foo>
<foo>159</foo>
ENDXML
my $dom = Mojo::DOM->new->xml(1)->parse($xml);
my $i = 1;
$dom->find('foo')->each(sub{ $_->content($i++) });
print $dom->to_string;
__END__
<foo>1</foo>
<foo>2</foo>
<foo>3</foo>
| [reply] [d/l] |
|
I certainly see your point about not trying to parse arbitrary HTML or XML with regular expressions, but in this case, I am looking for a specific tag with numeric values that have already been sanitized by another program.
That does lead me to a side question, though. Do you know of an HTML "cleanup" program (or module) that will take (mostly arbitrary) HTML and output one tag per line properly indented?
| [reply] |
|
I certainly see your point about not trying to parse arbitrary HTML or XML with regular expressions, but in this case, I am looking for a specific tag with numeric values that have already been sanitized by another program.
Can you trust the source of the XML to never change (whitspace, attributes, CDATA, namespaces, comments, etc.), and can you trust the program that's doing the sanitization to never change its output either? What's wrong with installing modules, especially such helpful ones? (Yes, even you can use CPAN.)
Sure, it's possible to adapt the regexes shown by the others to this purpose to work on the sample data you've showed, but I personally am not going to jump down the rabbit hole of parsing XML with regexes in this case :-)
Do you know of an HTML "cleanup" program (or module) that will take (mostly arbitrary) HTML and output one tag per line properly indented?
Searching for "html tidy" on Google and CPAN shows lots of different options (I haven't used any of them, so I can't give you recommendations). Plus, I wonder why you're asking about such a program, if you said above your XML is already sanitized? ;-)
| [reply] [d/l] [select] |
|
|
Re: sequential substitutions
by tybalt89 (Monsignor) on Aug 03, 2018 at 10:32 UTC
|
#!/usr/bin/perl
use strict;
use warnings;
my $fragment = '
<foo>3</foo>
<foo>14</foo>
<foo>159</foo>
[...]
';
print $fragment;
my $n = 1;
$fragment =~ s/\d+/ $n++ /ge;
print $fragment;
| [reply] [d/l] |
|
This is pretty much what I was looking for (actually, it is even more than I was looking for - I thought I would at a minimum have to loop over the matches with a while statement :) ). I already have it incorporated into my program, and it is working.
Thank you very much.
| [reply] |
Re: sequential substitutions
by choroba (Cardinal) on Aug 03, 2018 at 16:51 UTC
|
open file.xml ;
$i = 0;
for //foo set . {++$i} ;
save :b ;
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] [select] |
Re: sequential substitutions
by anonymized user 468275 (Curate) on Aug 03, 2018 at 10:08 UTC
|
As stated it is simple enough, but there is usually more to the story, requiring more complex parsing than just detecting digits and substituting.
( echo '<foo>3</foo>'; echo '<foo>14</foo>'; echo '<foo>159</foo>') |
+perl -e '
my $x = 0;
while (my $l = <>) {
$x++; $l =~ s/\d+/$x/;
print $l;
}'
<foo>1</foo>
<foo>2</foo>
<foo>3</foo>
| [reply] [d/l] |
|
There is a little bit more to it (but not much), and I do apologize for over-simplifying.
Let's suppose the code is actually:
<foo>3</foo>
<bar>a</bar>
<foo>14</foo>
<bar>bc</bar>
<foo>159</foo>
<bar>def</bar>
[...]
I want to simply echo lines that do not contain the "foo" tag to the output file. | [reply] [d/l] |
|
use strict;
use warnings;
my $i = 0;
while(<DATA>){
s/<foo>.*?<\/foo>/"<foo>".++$i."<\/foo>"/e;
print;
}
__DATA__
<foo>3</foo>
<bar>a</bar>
<foo>14</foo>
<bar>bc</bar>
<foo>159</foo>
<bar>def</bar>
| [reply] [d/l] |
|
|
|
Re: sequential substitutions
by Anonymous Monk on Aug 04, 2018 at 15:22 UTC
|
$text = '<foo>3</foo><foo>14</foo><foo>159</foo>';
while($text =~ /<foo>(.*?)<\/foo>/g)
{
push (@la,$1);
};
sort @la;
foreach(@la)
{
print "<foo>$_<\/foo>\n";
}
| [reply] [d/l] |
|
Sorry, but there are at least two things wrong with that code (aside from using regexes to parse HTML...): It does not re-number the entries as the OP specified, and sort @la; does nothing (should be @la = sort @la; instead, warnings would have told you about this). So really the only effect of this code is to remove any non-<foo> tags from the input and re-format it slightly.
| [reply] [d/l] [select] |