【发布时间】:2017-04-21 23:32:03
【问题描述】:
真正的快速背景:我们有一个 PDFMaker (HTMLDoc) 可以将 html 转换为 pdf。 HTMLDoc 不会始终从客户端提供给我们的 html 中获取我们需要的样式。因此,我试图转换诸如 style="width:80px;height:90px;" 之类的东西到高度=80 宽度=90。
到目前为止,我的尝试表明我对反向引用以及如何在 Perl Regex 中正确使用它们的理解有限。我可以获取输入文件并将其转换为输出文件,但它每行仅捕获一种“样式”,并且仅替换该 css 中的一个名称/值对。
我可能以错误的方式处理此问题,但我无法在 Perl 中找到更快或更智能的方法来执行此操作。任何帮助将不胜感激!
注意:我试图为这个特定脚本更改的唯一属性是“高度”、“宽度”和“边框”,因为我们的客户端使用了一种工具,该工具会自动将样式应用于他们通过所见即所得拖动的元素风格的编辑器。显然,使用正则表达式将这些从很多地方剥离出来效果很好,因为您只需让表格单元格根据其内容调整大小,这看起来还可以,但我想一个更快的方法来处理这个问题就是用“width”“height”和“border”属性替换这三个属性,它们的行为与它们的css对应物基本相同(除了CSS允许您实际自定义边框的宽度、颜色和样式,但它们都曾经use 是solid 1px,所以我可以添加一个条件来将“solid 1px”替换为“border=1”。我意识到这些并不完全等效,但对于这个应用程序来说,这将是一个步骤。
这是我目前得到的:
#!/usr/bin/perl
if (!@ARGV[0] || !@ARGV[1])
{
print "Usage: converter.pl [input file] [output file] \n";
exit;
}
open FILE, "<", @ARGV[0] or die $!;
open OUTFILE, ">", @ARGV[1] or die $!;
my $line;
my $guts;
while ( <FILE> ) {
$line = $_ ;
$line =~ /style=\"(.+)\"/;
$guts = $1;
$guts =~ /([a-zA-Z]+)\:([a-zA-Z0-9]+)\;/;
$name = $1;
$value = $2;
$guts = $name."=".$value;
$line =~ s/style=\"(.+)\"/$guts/g;
print OUTFILE $line ;
}
exit;
注意:这不是家庭作业,不,我不是要你为我做我的工作,这最终会成为一个内部工具,它只是加快了我们传入的 html 的格式化过程,以便在 pdf 中正常工作我们有转换器。
更新
对于那些感兴趣的人,我得到了一个初始工作版本。这个只替换了宽度和高度,我们现在正在废弃的边框属性。但是如果有人想看看我们是怎么做到的,那就看看吧……
#!/usr/bin/perl
## NOTES ##
# This script was made to simply replace style attributes with their name/value pair equivalents as attributes.
# It was designed to replace width and height attributes on a metric buttload of table elements from client data we got.
# As such, it's not really designed to handle more than that, and only strips the unit "PX" from the values.
# All of these can be modified in the second foreach loop, which checks for height and width.
if (!@ARGV[0] || !@ARGV[1])
{
print "Usage: quickvert.pl [input file] [output file] \n";
exit;
}
open FILE, "<", @ARGV[0] or die $!;
open OUTFILE, ">", @ARGV[1] or die $!;
my $line;
my $guts;
my $count = 1;
while ( <FILE> ) {
$line = $_ ;
my (@match) = $line =~ /style=\"(.+?)\"/g;
my $guts;
my $newguts;
foreach (@match) {
#print $_ ."\n";
$guts = $_;
$guts =~ /([a-zA-Z]+)\:([a-zA-Z0-9]+)\;/;
$newguts = "";
foreach my $style (split(/;/,$guts)) {
my ($name, $value) = split(/:/,$style);
$value =~ s/px//g;
if ( $name =~ m/height/g || $name =~ m/width/g ) {
$newguts .= "$name='$value' ";
} else {
$newguts .= "";
}
}
#print "replacing $guts with $newguts on line $count \n";
$line =~ s/style=\"$guts\"/$newguts/i;
}
#print $newguts;
print OUTFILE $line ;
$count++;
}
exit;
【问题讨论】:
-
不完全一样,但stackoverflow.com/questions/1271438/… 可能会给你一些想法。