【发布时间】:2011-01-30 02:26:56
【问题描述】:
我正在尝试使用正则表达式从文本文件中删除某些编码块。到目前为止,我的大部分正则表达式行都可以删除代码。但是,我有两个问题:
1) 每当我删除一段文本时,应该将文本替换为空格,而不是简单地被删除。 我的正则表达式代码的一个示例是:
$file =~ s/<ul(.*)>//gi;
这会删除所有基本格式为<ul...> 的行,这正是我想要的。但是,如前所述,它将标签和所有包含的数据替换为空格,我想知道如何停止这种特殊的替换。
2) 某些本应有效的正则表达式代码似乎无效。例如,我想删除
<script type="text/javascript">
function getCookies() { return ""; }
</script>
我尝试过使用各种正则表达式代码,但似乎没有什么可以删除这些行。例如:
$file =~ s/<script type(.*)<\/script>//gi;
分别删除<script type...>和</script>标签,但留下
function getCookies() { return ""; }
...完好无损。我不确定为什么会发生这种情况,我非常想纠正这个问题。这怎么可能?对这两个问题中的任何一个的任何帮助都会非常有帮助!
编辑:对不起,我正在使用 Perl! 另外:我刚刚尝试使用
$file =~ /<script type(.*)<\/script>/sgi
...以及 /msgi,但不幸的是,两者都不起作用。 <script type> 和 </script> 标签都被删除了,但由于某种原因
function getCookies() { return ""; }
...部分保留。这是我的整个代码,包括所有正则表达式:
use strict;
use warnings;
my $firstarg;
if ($ARGV[0]){
$firstarg = $ARGV[0];
}
open (DATA, $ARGV[1]);
my $file = do {local $/; <DATA>};
$file =~ s/<\!DOCTYPE(.*)>//gi;
$file =~ s/<html>//gi;
$file =~ s/<\/html>//gi;
$file =~ s/<title>//gi;
$file =~ s/<\/title>//gi;
$file =~ s/<head>//gi;
$file =~ s/<\/head>//gi;
$file =~ s/<link(.*)>//gi;
$file =~ s/<\link>//gi;
$file =~ s/CDM(.*)\;//gi;
$file =~ s/<\!(.*)->//gi;
$file =~ s/<body(.*)>//gi;
$file =~ s/<\/body>//gi;
$file =~ s/<div(.*)>//gi;
$file =~ s/<\/div>//gi;
$file =~ s/function(.*)>//gi;
$file =~ s/<noscript>//gi;
$file =~ s/<\/noscript>//gi;
$file =~ s/<a(.*)>//gi;
$file =~ s/<\/a>//gi;
$file =~ s/<ul(.*)>//gi;
$file =~ s/<\/ul>//gi;
$file =~ s/<li(.*)>//gi;
$file =~ s/<\/li>//gi;
$file =~ s/<form(.*)>//gi;
$file =~ s/<\/form>//gi;
$file =~ s/<iframe(.*)>//gi;
$file =~ s/<\/iframe>//gi;
$file =~ s/<select(.*)>//gi;
$file =~ s/<\/select>//gi;
$file =~ s/<textarea(.*)>//gi;
$file =~ s/<\/textarea>//gi;
$file =~ s/<b>//gi;
$file =~ s/<\/b>//gi;
$file =~ s/<H1>//gi;
$file =~ s/<H2>//gi;
$file =~ s/<H3>//gi;
$file =~ s/<H4>//gi;
$file =~ s/<H5>//gi;
$file =~ s/<H6>//gi;
$file =~ s/<\/H1>//gi;
$file =~ s/<\/H2>//gi;
$file =~ s/<\/H3>//gi;
$file =~ s/<\/H4>//gi;
$file =~ s/<\/H5>//gi;
$file =~ s/<\/H6>//gi;
$file =~ s/<option(.*)>//gi;
$file =~ s/<\/option>//gi;
$file =~ s/<p>//gi;
$file =~ s/<\/p>//gi;
$file =~ s/<span(.*)>//gi;
$file =~ s/<\/span>//gi;
$file =~ s/<!doctype(.*)>//gi;
$file =~ s/<base(.*)>//gi;
$file =~ s/<br>//gi;
$file =~ s/<hr>//gi;
$file =~ s/<img(.*)>//gi;
$file =~ s/<input(.*)>//gi;
$file =~ s/<link(.*)>//gi;
$file =~ s/<meta(.*)>//gi;
$file =~ s/<script type(.*)<\/script>//gi;
print $file;
好的,现在我删除了导致一个问题的 <script> 正则表达式,另一个已创建 - 使用:
$file =~ s/<script type(.*)<\/script>//gi;
删除<script ...> 的第一个实例之间的所有内容,但不删除标签本身,而不是整个标签的重复。使用:
$file =~ s/<script type(.*)<\/script>//mgi;
结果完全相同。使用:
$file =~ s/<script type(.*)<\/script>//sgi;
导致打印几个换行符,但没有其他文本,/msgi 相同。
呃,问题永远不会结束...... :(
新编辑:对于发布有关使用正则表达式解析 HTML 的问题,我深表歉意。我意识到编程社区内对这种做法存在相当大的反对意见(或尝试实践,因为这似乎经常失败)。但是,不幸的是,我不得不使用正则表达式来解析 selected HTML,这些 HTML 可以删除大部分(如果不是全部)HTML 标记。我不允许使用模块,尽管这是最明显和最简单的答案。
【问题讨论】:
-
因为
=~我假设你在这里写Perl?关于环境的更多信息会很有用:) -
对于#2,将 /gi 更改为 /msgi 以处理多行模式。
-
请查看我在答案链接中发布的解决方案,尤其是第二个。这就是使用解析器的原因。
-
请使用
HTML::TreeBuilder模块。如果您在阅读this 后还没有足够的动力这样做,我不知道什么能说服您。 -
我不允许在此作业中使用模块。它应该是纯正则表达式代码,减去输入/搜索代码。相信我,我很想使用一个模块,它会让我的生活变得更轻松。 :(