challenge 改行をBRタグに置き換える

一部のHTMLタグを通すフィルタ どう書く?の続編です。 前回の条件を満たしつつ、入力中の改行を<br/>に置き換えてください。ただし、たとえば"<a\nhref=...>"といったようにタグの中に改行がある場合、単純に置換するわけには行かないことに注意してください。

また、ユーザの入力注の<br>は<br/>に変換してください。

このお題はperezvonさんの提案を元にした三部作の二問目です。ご協力ありがとうございました。

Posted feedbacks - Perl

すみません。#3789はむしろこちらの答えです。前問題との答えの差をソースのコメントに書いておきます。

Dan
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/local/bin/perl
use strict;
use warnings;
use HTML::Parser;
use HTML::Entities;

sub parse {
    my $str = shift;
    my @parsed;
    my $p = HTML::Parser->new(
        start_h => [
            sub {
                my ( $t, $a, $text ) = @_;
                if ($t eq 'a'){
                    my @a =
                        map { qq/$_="/ . encode_entities($a->{$_}) . qq/"/ }
                            grep /^name|href$/, keys %$a;
                    push @parsed, "<a ".join(" ", @a). ">"
                }elsif($t eq 'br' || $t eq 'strong'){
                    push @parsed, "<$t>"
                }else{
                    push @parsed, encode_entities($text)
                }
            }, "tagname, attr, text"
        ],
        end_h => [
            sub {
                my $t = shift;
                push @parsed, $t =~ /^a|br|strong$/ ? "</$t>" : "&lt'/$t&gt;";
            }, "tagname"
        ],
        text_h => [
            sub {
                my $t = shift;
                $t =~ s{\n}{</br>}g; # ここの有無のみ異なる
                push @parsed, $t;
            }, "text"
        ]
    )->parse($str);
    join '', @parsed;
}

# for test
local $/;
my $str = <>;
print parse($str);

標準入力からドゾ
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#! /usr/bin/perl
sub E($){ local $_ = shift;
          s/([&<>"'])/sprintf('&#x%02X',ord $1)/eg;
          s/\x0d\x0a|[\x0d\x0a]/<br>\n/g; $_; }
sub T($){ local $_ = shift; no warnings;
          s#^<(/?strong)\b.*$#<$1>#i ? $_ :
          s#^<br[^>]*>#<br />#i      ? $_ :
          s#^</br[^>]*>#</br>#       ? $_ :
          s#^<(/?a\b)[^>]*?(\s?(?:href|name)=(?:'[^']*'|"[^"]*"|[^>\s]*))?
                     [^>]*?(\s?(?:href|name)=(?:'[^']*'|"[^"]*"|[^>\s]*))?
            [^>]*?>#<$1$2$3>#xi ? $_ : E $_;  }
$_ = join '', <>; s#(.*?)(</?\w+\b[^>]*>)#E($1).T($2)#seg; print;

Index

Feed

Other

Link

Pathtraq

loading...