使用 Perl 提取文件名

Extract filename with Perl

我正在编写一个脚本,它逐行读取多个文件,检查每一行的文件引用,然后检查这些文件是否存在。

在文件中我有这样的字符串: example 1: soundSet = { name = "bus_modern", horn = "vehicle/truck_modern/horn.wav" } example 2: id = "vehicle/bus/citaro/lod_0_w2.msh", example 3: "vehicle/bus/berkhof_duvedec/berkhof_duvedec_lod_0_w2.msh", "vehicle/bus/berkhof_duvedec/berkhof_duvedec_lod_0_w3.msh",

所以我需要以某种方式从字符串中提取文件名。 我目前的尝试是从字符串中删除所有空格,删除第一部分,包括 "-char 并在第二个 "-char 之后切掉所有内容。

这显然不适用于示例 1 和 3: 在示例 1 中,我在字符串的第二部分获得了我的文件引用,在示例 3 中,我有两个要提取的文件。

不,我很困惑,如何从给定的字符串中提取任何文件引用?

    open $filehandle, "<", $file or die "can't open $file\n";

    # read the whole file and check for references
    while (<$filehandle>)
    {
        my $line=$_;
        my $count=0;
       $count++ while ($line =~ m/\//g);
       # looks like we found a file-reference
        if ( $count > 1) 
        { 
           # remove all whitespace now

            # prefix whitespace
            $line =~ s/^\s+//;

            # suffix whitespace
            $line =~ ~ s/\s+$//;

            # intermediate whitespace
            $line=~ s/ //g;

            # cut until "
            $line=~ s/[^\"]*\"//;
            pdebug (2, "    rem-pre-\": $line \n");

            # chop off all chars after "
            my $oper = index($line, '"');
            my $word = substr($line, 0, $oper);
            $line=$word;


            # putting it together
            my $searchfile=buildpath($line);
            if ( -e $searchfile )
            {
                pdebug(1,"found\n");
            }
            else
            {
                pdebug(1,"not found\n");
                print "\nunmatched reference in file:\n$file\n";
                findline($file,$line);
                print"\ncouldn't find file:\n       $searchfile\nreferenced as:\n$line\n";


            }
        }

到目前为止,这是我的代码的相关部分。未显示的是我遍历目录结构以识别必须检查的每个文件的部分。 未在此处未显示的代码中使用的潜艇:

pdebug: 打印出 debugtext

findline:需要文件名和要搜索的字符串,打印出找到它的行号

构建路径:每个文件类型都属于一个子目录(即 audio/effects 中的 .wav,纹理中的 .tga),构建路径检查文件名和 returns 完整路径

有人能帮我找到正确的方向吗?

我认为最好只有一个正则表达式:

while (<$filehandle>)
{
   my @filenames = /(?<=")(?:\w+\/)*\w+[.]\w+(?:")/g;
   say join("$_\n", @filename) if @filename > 0;
}

请在此处查看正则表达式: https://regex101.com/r/bA4oZ7/1

'x' 修饰符允许编写多行正则表达式并在此处添加一些注释以解释您的正则表达式(可在此处获取:https://regex101.com/r/bA4oZ7/3

my $re qr/(?<=") # A filename is after a double quote char
(?:[^"\/]+\/)+   # the path is one or more words separated with a slash
[^"\/]+          # The filename (not the path) can be anything but a double quote char and a slash
[.]\w+           # The extension cannot have space and have the form of .foobar
(?:")            # A filename end with a double quote char
/gx;

...
my @filenames = /$re/g;