通常、HTML の解析に正規表現を使用しないでください。代わりに、 Mojo::DOMのような HTML パーサーを使用する必要があります。
use strict;
use warnings 'all';
use Mojo::DOM;
# Add the appropriate kramdown list marker to a Mojo::DOM node representing a
# single <li>, depending on whether it's in an <ol> or <ul>
sub add_list_marker {
my ($node, $i) = @_;
my $marker = $node->parent->tag eq 'ol' ? "$i. " : '- ';
$node->prepend_content($marker);
}
# Convert a Mojo::DOM node representing an <ol> or <ul> to the corresponding
# kramdown
sub list_to_kramdown {
my ($node) = @_;
my $items = $node->children('li')->each(\&add_list_marker);
my $text = $items->map('text')->join("\n");
$node->replace("\n$text\n");
}
my $html = do {
local $/;
<DATA>
};
my $dom = Mojo::DOM->new($html);
$dom->find('ol, ul')->each(\&list_to_kramdown);
print $dom->to_string;
__DATA__
<h1>Leave surrounding HTML</h1>
<div id="including_enclosing_tags">
<ol>
<li>foo</li>
<li>bar</li><li>baz</li>
<li>qux</li>
</ol>
<ul>
<li class="fruit">apple</li>
<li>pear</li>
<li>banana</li>
<li>pine
apple</li>
</ul>
</div>
出力:
<h1>Leave surrounding HTML</h1>
<div id="including_enclosing_tags">
1. foo
2. bar
3. baz
4. qux
- apple
- pear
- banana
- pine apple
</div>
これは、以下を簡単に処理できるため、正規表現よりも優れています。
- 同じ行に複数の
<li>
要素
<li>
複数行にわたる要素
- 属性を持つ要素