字符串eq中未初始化的值$ 4 - Perl

时间:2012-08-24 16:21:19

标签: xml regex perl

@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的新手。有人可以帮助我吗?

4 个答案:

答案 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 ...

会更好/更好

此致