2

我正在寻找从多行文本字符串中挖掘出一些好东西。我很乐意在 Perl 中执行正则表达式(尽管我确信有比我下面的代码更好的方法),但并不真正了解如何在正则表达式中使用标记的字符串作为 Javascript 中 newSubStr 的一部分。有没有办法或者我是否坚持运行多个替换来放弃音频和源线?

$_ = <<END;
<audio controls="controls" preload="metadata">
   <source src="01.mp3" type="audio/mpeg">
   <source src="01.ogg" type="audio/ogg">
   Stuff
   Default: <a href="01.mp3">&gt;&gt;download</a>
</audio>
END

s#.*<source.*?>.*?\n(.*)\n</audio>.*#$1#s;

print "[$_]\n";

(我有限的)Javascript中的倍数正则表达式可能像这样:

// We're really dependent on the HTML layout for line feeds
// so watch out.
var line = aElems[i].innerHTML.replace(/.*?audio.*?\n/gm, '');
var line2 = line.replace(/.*<source.*?\n/mg, '');
console.log(line2);
4

2 回答 2

3

尽管您说您想使用 JavaScript,但我想我会向您展示非正则表达式 Perl 方法。HTML::TokeParser::Simple让它变得非常简单:

use HTML::TokeParser::Simple;
my $p = HTML::TokeParser::Simple->new( *DATA );

TOKEN: while( my $token = $p->get_token ) {
    if( $token->is_start_tag( 'audio' ) ){
        AUDIO: while( my $t = $p->get_token ) {
            next AUDIO if $t->is_tag( 'source' );
            last AUDIO if $t->is_end_tag( 'audio' );
            print $t->as_is;
            }
        next TOKEN;
        }

    print $token->as_is;
    }

__DATA__
<html>
<head><title>Test</title></head>
<body>
<p>Keep this</p>
<audio controls="controls" preload="metadata">
   <source src="01.mp3" type="audio/mpeg">
   <source src="01.ogg" type="audio/ogg">
   Stuff
   Default: <a href="01.mp3">&gt;&gt;download</a>
</audio>
<p>Keep this</p>
</body>
</html>

这给出了:

<html>
<head><title>Test</title></head>
<body>
<p>Keep this</p>



   Stuff
   Default: <a href="01.mp3">&gt;&gt;download</a>

<p>Keep this</p>
</body>
</html>

还有其他 Perl 模块也可以正确解析 HTML 并使用该结构。

对于 JavaScript 方面,为什么不直接替换 HTML?我知道你问了一个相关的问题。在我看来,应该有其他东西在音频中生成内容,并且在这种情况下应该能够为您提供您喜欢的东西。我会后退一步并继续努力。或者,您可以详细解释您的问题。

于 2012-04-04T18:03:55.737 回答
2

通过阅读您的两个问题,听起来您真正想要的是使音频标签的父标签包含音频标签的 innerHTML 并删除源元素。

正则表达式很容易出错,尤其是当您可以使用 DOM 以更少的努力获得相同的结果时。

var audio_tag = ...;
var elements_to_delete = audio_tag.getElementsByTagName('source');
for (var idx = elements_to_delete.length - 1; idx >= 0; --idx) {
    audio_tag.removeChild( elements_to_delete[idx] );
}
audio_tag.parentNode.innerHTML = audio_tag.innerHTML;
于 2012-04-04T19:46:04.347 回答