我正在尝试编写一个Perl脚本,它将改变一个看起来像这样的行......
<li><em>01 – Chapters 1-4</em> – 00:14:36 <br />
......让它看起来像这样......
01 – Chapters 1-4
......没什么大不了的?我只是在我的Perl脚本中执行\(.*\)
这样的事情:
#!/usr/bin/perl -w
use strict;
while(<DATA>) {
my $line = $_;
chomp($line);
if ( $line =~ /^<li>/ ) {
$line =~ s/<em>\(.*\)<\/em>/$1/g;
print "[" . $line . "]\n";
}
}
__DATA__
<li><em>01 – Chapters 1-4</em> – 00:14:36 <br />
<li><em>02 – Chapters 5-8</em> – 00:10:52 <br />
<li><em>03 – Chapters 9-14</em> – 00:19:16 <br />
<li><em>04 – Chapters 15-18</em> – 00:13:30 <br />
<li><em>05 – Chapters 19-22</em> – 00:17:01 <br />
<li><em>06 – Chapters 23-25</em> – 00:16:44 <br />
<li><em>07 – Chapter 26</em> – 00:10:35 <br />
red@ubuntu:~/scripts$ ./test.pl
当我运行脚本时,我得到了这个输出......
[<li><em>01 – Chapters 1-4</em> – 00:14:36 <br />]
[<li><em>02 – Chapters 5-8</em> – 00:10:52 <br />]
[<li><em>03 – Chapters 9-14</em> – 00:19:16 <br />]
[<li><em>04 – Chapters 15-18</em> – 00:13:30 <br />]
[<li><em>05 – Chapters 19-22</em> – 00:17:01 <br />]
[<li><em>06 – Chapters 23-25</em> – 00:16:44 <br />]
[<li><em>07 – Chapter 26</em> – 00:10:35 <br />]
......我在这里做错了什么?
由于
更新:
感谢您的所有回复。他们非常有帮助。 我已将代码更改为此...
red@ubuntu:~/scripts$ cat test.pl
#!/usr/bin/perl -w
use strict;
while(<DATA>) {
my $line = $_;
chomp($line);
if ( $line =~ /^<li>/ ) {
$line =~ s/<em>(.*)<\/em>/$1/g;
print "[" . $line . "]\n";
}
}
__DATA__
<li><em>01 – Chapters 1-4</em> – 00:14:36 <br />
<li><em>02 – Chapters 5-8</em> – 00:10:52 <br />
<li><em>03 – Chapters 9-14</em> – 00:19:16 <br />
<li><em>04 – Chapters 15-18</em> – 00:13:30 <br />
<li><em>05 – Chapters 19-22</em> – 00:17:01 <br />
<li><em>06 – Chapters 23-25</em> – 00:16:44 <br />
<li><em>07 – Chapter 26</em> – 00:10:35 <br />
...但仍然没有达到输出我希望我得到这个......
red@ubuntu:~/scripts$ ./test.pl
[<li>01 – Chapters 1-4 – 00:14:36 <br />]
[<li>02 – Chapters 5-8 – 00:10:52 <br />]
[<li>03 – Chapters 9-14 – 00:19:16 <br />]
[<li>04 – Chapters 15-18 – 00:13:30 <br />]
[<li>05 – Chapters 19-22 – 00:17:01 <br />]
[<li>06 – Chapters 23-25 – 00:16:44 <br />]
[<li>07 – Chapter 26 – 00:10:35 <br />]
...看起来已移除<em>
和</em>
,但我只想要<em>
和</em>
之间的文字。
答案 0 :(得分:6)
您只替换更新版本中匹配的部分行。
print "[$1]\n" if /<em>(.*)<\/em>/;
只会为您提供(.*)
捕获组捕获的内容。然后你不必费心去替换。
但请注意安迪莱斯特在评论中的谨慎态度。这很好用,或者你的测试数据很好,但是HTML因打破你的正则表达而臭名昭着,特别是如果你说了一句神奇的短语“但我真正的HTML数据总是完全采用这种形式”。
答案 1 :(得分:3)
您正在使用与\(.*\)
和(
匹配的)
。使用(.*)
提取匹配项。
根据您的更新...您需要使用以下
$line =~ s/<em>(.*)<\/em>(.*)/$1/g;
我强烈建议您考虑合并@ AndyLester的评论。
答案 2 :(得分:2)
如果你想捕捉,你想要
(...)
Escaped parens试图匹配parens。
答案 3 :(得分:2)
您所做的就是从字符串的第一部分周围删除<em>
标记。如果你想删除其他所有内容,请写下
use strict;
use warnings;
while(<DATA>) {
print "[$1]\n" if /^<li><em>([^<>]+)/;
}
__DATA__
<li><em>01 – Chapters 1-4</em> – 00:14:36 <br />
<li><em>02 – Chapters 5-8</em> – 00:10:52 <br />
<li><em>03 – Chapters 9-14</em> – 00:19:16 <br />
<li><em>04 – Chapters 15-18</em> – 00:13:30 <br />
<li><em>05 – Chapters 19-22</em> – 00:17:01 <br />
<li><em>06 – Chapters 23-25</em> – 00:16:44 <br />
<li><em>07 – Chapter 26</em> – 00:10:35 <br />
<强>输出强>
[01 – Chapters 1-4]
[02 – Chapters 5-8]
[03 – Chapters 9-14]
[04 – Chapters 15-18]
[05 – Chapters 19-22]
[06 – Chapters 23-25]
[07 – Chapter 26]
答案 4 :(得分:1)
您的第一次和第二次尝试包括以下内容:
$line =~ s/<em>\(.*\)<\/em>/$1/g; # First version
$line =~ s/<em>(.*)<\/em>/$1/g; # Second version
两个版本都没有对行的右端进行任何更改。命令s/f/r/
表示搜索匹配f
的内容并用r
替换该部分,隐式命令意味着对字符串的其余部分不执行任何操作。
将命令编写为
$line =~ s/<em>(.*)<\/em>.*/$1/g;
说要找到(在em>
之后)任意数量的字符,但不包括行尾或换行符。因此命令将删除其他想要的字符。
s///
命令可以使用其他字符作为分隔符,这样可以更轻松地搜索包含/
的字符串。所以上面的内容可能会更清楚地写成
$line =~ s!<em>(.*)</em>.*!$1!g;
在您给出的示例中,无需修改字符串。所描述的任务是在<em>
和</em>
对中打印文本并丢弃该行的其余部分。所以msw的答案中的代码可以满足所有需要。如果你正在处理大量性能很重要的文本,那么msw的方法可能更合适。