如何打印Perl字符类?

5

今天早上我参加了一次代码审查,发现了一段错误的代码,但是我不知道为什么。

$line =~ /^[1-C]/;

这行代码本应该评估一个十六进制字符,介于1C之间,但我认为这行代码并没有做到。问题不在于它匹配了什么,而是它匹配了什么?我能打印出字符类中的所有字符吗?就像下面这样:

say join(', ', [1-C]);

很遗憾,

# Examples:
say join(', ', 1..9);
say join(', ', 'A'..'C');
say join(', ', 1..'C');

# Output
Argument "C" isn't numeric in range (or flop) at X:\developers\PERL\Test.pl line 33.

1, 2, 3, 4, 5, 6, 7, 8, 9
A, B, C

虽然这不是直接相关的问题,但应该指出匹配介于1到C之间的十六进制数的正确正则表达式为/[0-9A-C]/ - bpj
3个回答

16

它匹配从 U+0030("1")到 U+0043("C")的每个代码点。

简单的答案是使用

map chr, ord("1")..ord("C")

取代

"1".."C"

正如你在下面的演示中所看到的:

$ perl -Mcharnames=:full -E'
   say sprintf " %s  U+%05X %s", chr($_), $_, charnames::viacode($_)
      for ord("1")..ord("C");
'
 1  U+00031 DIGIT ONE
 2  U+00032 DIGIT TWO
 3  U+00033 DIGIT THREE
 4  U+00034 DIGIT FOUR
 5  U+00035 DIGIT FIVE
 6  U+00036 DIGIT SIX
 7  U+00037 DIGIT SEVEN
 8  U+00038 DIGIT EIGHT
 9  U+00039 DIGIT NINE
 :  U+0003A COLON
 ;  U+0003B SEMICOLON
 <  U+0003C LESS-THAN SIGN
 =  U+0003D EQUALS SIGN
 >  U+0003E GREATER-THAN SIGN
 ?  U+0003F QUESTION MARK
 @  U+00040 COMMERCIAL AT
 A  U+00041 LATIN CAPITAL LETTER A
 B  U+00042 LATIN CAPITAL LETTER B
 C  U+00043 LATIN CAPITAL LETTER C
如果你安装了Unicode::Tussle,你可以通过以下 shell 命令获得相同的输出结果:

如果您已经安装了 Unicode::Tussle,您可以通过以下 shell 命令获得相同的输出结果:

unichars -au '[1-C]'

你可能会对浏览Unicode代码表感兴趣。(这个特定范围被称为“基本拉丁字符(ASCII)”。)


@Cyborgx37,谢谢。我刚刚让它变得更好了 :) - ikegami
我很喜欢使用map和“从U+0030(“1”)到U+0043(“C”)”,这正是我需要了解的。谢谢 - Eric Fossum

3
这是一个简单的程序,用于测试该正则表达式的范围:
use strict;
use warnings;
use Test::More qw(no_plan);

for(my $i=ord('1'); $i<=ord('C'); $i++ ) {
   my $char = chr($i);
   ok $char =~ /^[1-C]/, "match: $char";
}

生成以下结果:
ok 1 - match: 1
ok 2 - match: 2
ok 3 - match: 3
ok 4 - match: 4
ok 5 - match: 5
ok 6 - match: 6
ok 7 - match: 7
ok 8 - match: 8
ok 9 - match: 9
ok 10 - match: :
ok 11 - match: ;
ok 12 - match: <
ok 13 - match: =
ok 14 - match: >
ok 15 - match: ?
ok 16 - match: @
ok 17 - match: A
ok 18 - match: B
ok 19 - match: C
1..19

0

[1-9A-C] 匹配 1 到 C 之间的十六进制数

[一个字符-另一个字符] 匹配 Unicode 表中两个字符之间的所有字符


问题不在于哪些匹配,而是这个匹配的是什么。我认为,提问者并非在寻找正确的解决方案,而是想知道如何展示一个字符范围的匹配情况。也许他需要证明字符类别是错误的。 - JDB
当然可以,但他可以查阅维基百科的字符表以了解相关信息。 - Casimir et Hippolyte
1
你知道,我知道,但我不认为原帖作者知道。无论如何,这并没有真正回答问题,这可能解释了为什么会被踩。 - JDB
1
我认为原帖作者正在寻找一种编程方式,尽管我不认为你对它的解释配得上一个踩。 - ikegami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接