@files = glob "*.xml";
undef $/;
for $file (@files) {
$indent = 0;
open FILE, $file or die "Couldn't open $file for reading: $!";
$_ = readline *FILE;
close FILE or die "Couldn't close $file: $!";
# Remove whitespace between > and < if that is the only thing separating them
s/(?<=>)\s+(?=<)//g;
# Indent
s{ # Capture a tag <$1$2$3>,
# a potential closing slash $1
# the contents $2
# a potential closing slash $3
<(/?)([^/>]+)(/?)>
# Optional white space
\s*
# Optional tag.
# $4 contains either undef, "<" or "</"
(?=(</?))?
}
{
# Adjust the indentation level.
# $3: A <foo/> tag. No alteration to indentation.
# $1: A closing </foo> tag. Drop one indentation level
# else: An opening <foo> tag. Increase one indentation level
$indent +=
$3 ? 0 :
$1 ? -1 :
1;
# Put the captured tag back into place
"<$1$2$3>" .
# Two closing tags in a row. Add a newline and indent the next line
($1 and ($4 eq "</") ?
"\n" . (" " x $indent) :
# This isn't a closing tag but the next tag is. Add a newline and
# indent the next line.
$4 ?
"\n" . (" " x $indent) :
# This isn't a closing tag - no special indentation. I forget why
# this works.
""
)
# /g repeat as necessary
# /e Execute the block of perl code to create replacement text
# /x Allow whitespace and comments in the regex
}gex;
open FILE, ">", $file or die "Couldn't open $file for writing: $!";
print FILE or die "Couldn't write to $file: $!";
close FILE or die "Couldn't close $file: $!";
}
我正在使用此代码正确缩进一堆xml文件。但是,当我执行时,我得到:
Use of uninitialized value $4 in string eq at C:/Users/souzamor/workspace/Parser/xmlreformat.pl line 25.
和line 25
是:
# $4 contains either undef, "<" or "</"
我不知道为什么,我是Perl
的新手。有人可以帮助我吗?
答案 0 :(得分:4)
$4
是指正则表达式中的第四个捕获括号,在本例中为(?=(</?))?
。正如评论所述,这可能是未定义的,因为最后的?
意味着“这件事可能存在,但也可能不存在”。
如果您以某种方式使用未定义的值(通过Perl中的特殊值undef
发出信号),包括与eq
的字符串比较,则会收到来自Perl的警告。您可以使用defined($var)
轻松检查变量是否已定义。
在您的特定情况下,$4
用于此短语:
($1 and ($4 eq "</") ? "\n" . (" " x $indent) :
$4 ? "\n" . (" " x $indent) :
""
修复警告就像用这个替换这些测试一样简单:
($1 and defined($4) and ($4 eq "</") ? "\n" . (" " x $indent) :
$4 ? "\n" . (" " x $indent) :
""
请注意,在这种特殊情况下,您不必在第二行检查defined($4)
,但也不会受到影响。
答案 1 :(得分:0)
除非那里没有最终匹配:
(?=(</?))?
如果最后一个问号允许匹配继续进行替换,则$4
将为undef
。例如(使用Perl 5.10或更高版本,对于旧版本,使用||
代替//
应该是安全的):
(($4 // '') eq "</")
你只需要防范或关闭警告。您无法在零宽度前瞻之外移动捕获,因为这将始终将$4
设置为空字符串。
答案 2 :(得分:0)
所以这个运行时错误告诉你,给定你当前的输入,4美元没有价值,但无论如何你都在访问它。
所以行:
# Optional tag.
# $4 contains either undef, "<" or "</"
撒谎。如果$ 4是undef,那么您将收到有关未定义值而不是未初始化值的投诉。
$ 4在执行此s {} {}语句时不匹配任何内容。
除非你必须编写一个XML漂亮的打印机,否则你应该从CPAN中获得一个。
答案 3 :(得分:-2)
如果它正常工作,那么您可以忽略警告。改变这一行
close FILE or die "Couldn't close $file: $!";
到
close FILE or die "Couldn't close $file: $!";
no warnings 'uninitalized';
但是使用一些xml解析器库来解析xml ...
会更好/更好此致