Perl 字符串连接的奇怪行为

Posted

技术标签:

【中文标题】Perl 字符串连接的奇怪行为【英文标题】:Weird behavior with Perl string concatenation 【发布时间】:2011-09-07 00:43:30 【问题描述】:

我正在编写一个非常简单的脚本,读取 maplist.txt 文件并使用其中的 \n 分隔地图名称来构建命令字符串 - 但是,我遇到了一些意外行为。

我的完整代码:

# compiles a map pack from maplist.txt
# for every server.
# Filipe Dobreira <dobreira@gmail.com>
# v1 @ Sept. 2011

use strict;
my @servers = <*>;
foreach my $server (@servers)

        # we only want folders:
        next if -f $server;
        print "server: $server\n";

        my $maplist = $server . '/orangebox/cstrike/maplist.txt';
        my $mapdir  = $server . '/orangebox/cstrike/maps';

        print "   maplist: $maplist\n";
        print "   map folder: $mapdir\n";

        # check if the maplist actually exists:
        if(!(-e $maplist))
        
                print "!!! failed to find $maplist\n";
                next;
        

        open MAPLIST, "<$maplist";
        foreach my $map (<MAPLIST>)
        
                chomp($map);
                next if !$map;

                # full path to the map file:
                my $mapfile = "$mapdir/$map.bsp";
                print "$mapfile\n";
        

在我声明 $mapfile 的地方,我希望结果类似于:

zombieescape1/orangebox/cstrike/maps/ze_stargate_escape_v8.bsp

但是,似乎正在对字符串的 START 进行连接,最终结果类似于:

.bspiescape1/orangebox/cstrike/maps/ze_stargate_escape_v8

所以.bsp 部分实际上是写在最左边字符串的开头。我对 perl 的经验很少,我只能假设这是我无法理解某些怪癖或操作员的行为。

注意:我也尝试过使用"$mapdir/$map.bsp",用点运算符和join "", $mapdir, $map, ".bsp" 连接所有内容,结果相同。

提前致谢。

PS:作为参考,这是maplist.txt的样子:

zm_3dubka_v3
zm_4way_tunnel_v2
zm_abstractchode_pyramid2
zm_anotheruglyzmap_v1e
zm_app7e_betterbworld_JDfix_v3
zm_atix_helicopter_mini
zm_base_winter_beta3
zm_battleforce_panic_ua
zm_black_lion_macd_v8
zm_bunker_f57_v2
zm_burbsdelchode_b3
zm_choddarena_b12
zm_choddasnowpanic_b4
zm_citylife_V2b
zm_crazycity
zm_deep_thought_nv
zm_desert_fortress_v2
ZM_desprerados_a1
zm_doomlike_station_v2
zm_dust_arena_v1_final
zm_exhibit_night_2F
zm_facility_v1
zm_farm3_nav72
zm_firewall_samarkand
zm_fortress_b7
zm_ghs_flats
zm_gl33m4x_errata
zm_idm_hauntedhouse_v1
zm_industry_v2
zm_kruma_kakariko_village_006
zm_kruma_panic_004
zm_lila_off!ce_v4
zm_little_city_v5pf_fix
zm_moonlight_v3_pF
zm_moon_roflicious_pF_02
zm_moocbblechode_b2
zm_mountain_b2
zm_neko_abura_v2
zm_neko_athletic_park_v2
zm_novum_v3_JDfix
zm_ocx_orly_v4
zm_officeattack_b5a
zm_officerush_betav7
zm_officesspace_pfss
zm_omi_facility_pfv2
zm_penumbra_PF3
zm_raindance_ak_v2
zm_roflicious_pfcf2
zm_roy_abandoned_canals_new
zm_roy_barricade_factory
zm_roy_highway
zm_roy_industrial_complex
zm_roy_old_industrial_pF
zm_roy_the_ship_pf
zm_roy_zombieranch_night_b4
zm_survival_f2a
zm_temple_v3pf
zm_towers_v3
zm_tx_highschool_zkedit_v2
zm_unpanicv2_pF
zm_vc2_office_redone_b1
zm_wasteyard_beta3
zm_winterfun_b4a
zm_wtfhax_v6
zm_wtfhax_v6e
zm_wwt_twinsteel_v8

【问题讨论】:

你在什么操作系统上运行这个? @ennukiller: Linux 版本 2.6.39-pf2 (...) (gcc 版本 4.4.5 (Gentoo 4.4.5 p1.2, pie-0.4.5) ) (...) 我无法重现您的问题,可以尝试以下方法: 打开一个新的 xterm 并运行它 有时 xterm 上的设置会被破坏;是否有可能您有 2 个相同的进程运行两次?确保您已打开自动刷新 $| =1 【参考方案1】:

我猜maplist.txt 有非 unix 行结尾 - 可能是 dos - 结果你会看到 看起来像 前置。

问题是 chomp() 只使用两个行尾字符之一,而将回车留在后面。

您可能会发现,如果您在打开地图列表之前设置 Perl special variable $/(输入记录分隔符),那么 chomp 就会完成这项工作 - 它将消耗两个行尾字符。

$/ = qq\r\n;

另一种解决方案是在处理之前转换文件中的行尾,可能使用dos2unix。

【讨论】:

宾果游戏!我猜有人在 Windows 上编辑了文件,或者让它经历了一些 Filezilla 的怪异。非常感谢! @Filipe,与马丁·克莱顿的解决方案不同,open MAPLIST, "&lt;:crlf", $maplist; 将以 CRLF 或仅 LF 结尾的行工作,因此将使用 $map =~ s/\s+\z//; 而不是 chomp($map);。我推荐后者。

以上是关于Perl 字符串连接的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

nvarchar 连接 / 索引 / nvarchar(max) 莫名其妙的行为

MS Access Professional Plus 2019 的 Perl 连接字符串

带有 sql 连接字符串的 perl 脚本看似故障转移点(。)

从服务器端关闭连接时的 QAbstractSocket 奇怪行为

Android WebSocket - 断开连接检测奇怪的行为

为啥字符串连接在 C++ 中得到奇怪的结果? [关闭]