You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Perl实现大小写排序遇问题:无法提取大写单词

问题分析与解决

你的代码存在两个核心问题,导致无法提取并区分大写单词:

  1. 丢失大小写信息:统计阶段直接把所有单词转成小写(lc($word))作为哈希键,原始的大写单词信息被完全覆盖,后续根本无法区分大小写变体。
  2. 排序逻辑混乱:排序部分的sort {"\$a" cmp uc"\$b"} lc($word)完全不符合Perl语法——lc($word)是单个字符串,sort无法对单个元素排序,且比较逻辑完全错误。

修正后的代码

统计单词(保留大小写信息)

my %word_stats;
my $filename = "electricity.txt";
# 增加文件打开错误处理,避免静默失败
open my $fh, '<', $filename or die "无法打开文件 $filename: $!";

while (my $line = <$fh>) {
    chomp $line;
    # 用非单词字符分割,提取纯单词(跳过分割产生的空字符串)
    foreach my $word (split /\W+/, $line) {
        next if $word eq '';
        my $lower_word = lc($word);
        # 用小写单词分组统计次数,同时保存该分组下的所有大小写变体
        $word_stats{$lower_word}{count}++;
        $word_stats{$lower_word}{variants}{$word} = 1;
    }
}
close $fh;

按要求排序输出

print "\n\n按字母排序,首字母相同的大写单词排在小写单词前面:\n";

# 先按小写字母顺序对分组键排序
foreach my $lower_key (sort keys %word_stats) {
    # 对当前分组内的大小写变体排序:大写在前,同组单词按字母顺序排列
    my @sorted_words = sort {
        uc($a) cmp uc($b) || $a cmp $b
    } keys %{$word_stats{$lower_key}{variants}};
    
    foreach my $word (@sorted_words) {
        printf "%-31s 出现次数: %d\n", $word, $word_stats{$lower_key}{count};
    }
}

关键修正说明

  • 保留大小写信息:用小写单词作为分组键统计次数,同时在分组内存储所有原始大小写的单词变体,既保证统计准确,又不丢失大小写特征。
  • 合理分割单词:使用/\W+/分割文本,避免将标点符号和单词混为一谈(比如原代码会把"问题是:"当成一个单词,修正后能提取出纯单词"问题是")。
  • 正确排序逻辑:先按不区分大小写的规则分组,同一分组内再通过$a cmp $b让大写单词排在前面(大写字母的ASCII码小于小写)。

内容的提问来源于stack exchange,提问作者baishakh22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:10:40