Perl 整数常量
Perl 中的整数常量可以是
- 如果它们以
^0x 开头,则以 16 为基数
- 如果它们以
^0b 开头,则以 2 为基数
- 如果它们以
0 开头,则以 8 为基数
- 否则它们以 10 为底。
在该前导之后是该基数中任意数量的有效数字以及可选的下划线。
注意数字不代表\p{POSIX_Digit};它的意思是\p{Decimal_Number},这真的很不一样,你知道的。
请注意,任何前导减号不是整数常量的一部分,这很容易证明:
$ perl -MO=Concise,-exec -le '$x = -3**$y'
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 <$> const(IV 3) s
4 <$> gvsv(*y) s
5 <2> pow[t1] sK/2
6 <1> negate[t2] sK/1
7 <$> gvsv(*x) s
8 <2> sassign vKS/2
9 <@> leave[1 ref] vKP/REFC
-e syntax OK
看到 3 const,以及很久以后的 negate 操作码?这会告诉你很多信息,包括对优先级的好奇。
Perl 标识符
通过符号解引用指定的标识符对它们的名称绝对没有任何限制。
- 例如,
100->(200) 使用参数(100, 200) 调用名为100 的函数。
- 另一方面,
${"What’s up, doc?"} 在当前包中通过该名称引用标量包变量。
- 另一方面,
${"What's up, doc?"} 指的是名称为${"s up, doc?"} 的标量包变量,它在当前包中不是,而是在What 包中。当然,除非当前包是What 包。与$Who's 类似的是Who 包中的$s 变量。
也可以有${^标识符}形式的标识符;这些不被视为对符号表的符号取消引用。
单个字符的标识符可以是标点符号,包括$$或%!。
标识符也可以是$^C 的形式,它可以是控制字符或后跟非控制字符的抑扬符。
如果这些都不成立,则(非完全限定)标识符遵循与具有属性 ID_Start 的字符相关的 Unicode 规则,然后是具有属性 ID_Continue 的字符。但是,它推翻了这一点,允许全数字标识符和以下划线开头(并且可能没有其他内容)的标识符。您通常可以假装(但实际上只是假装)这就像说\w+,其中\w 与Annex C of UTS#18 中的描述相同。也就是说,任何有这些的东西:
- Alphabetic 属性——它不仅仅包括字母;它还包含各种组合字符和 Letter_Number 代码点,以及带圆圈的字母
- Decimal_Number 属性,它不仅仅是
[0-9]
- 任何和所有具有 Mark 属性的字符,而不仅仅是那些被视为 Other_Alphabetic 的标记
- 任何具有 Connector_Puncutation 属性的字符,下划线就是其中之一。
所以要么^\d+$ 要么
^[\p{Alphabetic}\p{Decimal_Number}\p{Mark}\p{Connector_Punctuation}]+$
如果您不想探索 Unicode ID_Start 和 ID_Continue 属性的复杂性,则应该为真正简单的那些做它。这就是它的真正完成方式,但我敢打赌你的教练不知道这一点。也许有人不会告诉他,嗯?
但你应该涵盖我之前描述的不简单的那些。
而且我们还没有讨论包。
标识符中的 Perl 包
除了这些简单的规则之外,您还必须考虑标识符可以用包名来限定,而包名本身遵循标识符的规则。
包分隔符是:: 或',随心所欲。
如果包是完全限定标识符中的第一个组件,则不必指定包,在这种情况下,它表示包main。这意味着像$::foo 和$'foo 等价于$main::foo,而isn't_it() 等价于isn::t_it()。 (Typo removed)
最后,作为一种特殊情况,允许在哈希末尾使用尾随双冒号(但不是单引号),然后 this 引用该名称的符号表。
因此%main:: 是main 符号表,因为您可以省略main,所以%:: 也是如此。
同时,%foo:: 是 foo 符号表,%main::foo:: 和 %::foo:: 也是为了变态。
总结
很高兴看到教师给人们布置非平凡的任务。问题是教练是否意识到这不是微不足道的。应该不会吧。
而且不仅仅是 Perl。关于 Java 标识符,您是否发现教科书在撒谎?这是演示:
$ perl -le 'print qq(public class escape { public static void main(String argv[]) { String var_\033 = "i am escape: ^\033"; System.out.println(var_\033); }})' > escape.java
$ javac escape.java
$ java escape | cat -v
i am escape: ^[
是的,这是真的。许多其他代码点也是如此,特别是如果您在编译行上使用-encoding UTF-8。您的工作是找到描述这些令人吃惊的不受禁止的 Java 标识符的模式。 提示:确保包含代码点 U+0000。
你不高兴你问了吗?希望这可以帮助。或者其他的东西。 ☺