给定一个字符串,我想要
A
的所有字符设置为 I
的第 8 位(0x41
~ 0x49
到 0xC1
~ 0xC9
)。喜欢,
$s='@ABCDEFGHIJKLMNOPQRS';
$s1= join "", map { $_ |= 0x80 if /A-I/ } split //, $s;
$s2= join "", map { $_ &= ~0x80 } split //, $s1;
我认为我上面的代码很接近,但它并没有完全工作。
请帮忙。
您的代码有一些问题。
首先,传递给
map
的函数必须返回所需的值。您的代码将 $_
设置为所需的值(这很好,但没有必要),但是 $s1
的代码没有返回结果,因此最终得到一个空字符串。 (您的 $s2
代码确实返回了结果,因此在这方面没有问题,尽管写得有点奇怪。)
其次,
/A-I/
不是正确的正则表达式。你本来想写 /[A-I]/
。
第三,当 Perl 在字符串和数字之间进行转换时(例如,因为您使用字符串和数字调用了按位运算符),它是通过将字符串解析为数字或以 10 为基数格式化数字来实现的。例如,
'3' | 12
相当于 3 | 12
,即 15
,然后根据需要转换为 '15'
。那不是你想要的;相反,您对字符串中字符的 ASCII/Unicode/字节值感兴趣。对于此类转换,您需要使用 ord
(字符→数字)和 chr
(数字→字符)。但你不能写chr(~0x80)
,因为~0x80
是0xFFFFFFFFFFFFFF7F
(假设是64位系统),这不是一个有效的字符代码。相反,您需要编写 chr(0x7F)
或 "\x7F"
,或者在按位运算之后应用 chr
,例如: chr(ord($_) & ~0x80)
。所以,把它们放在一起,你可以写成这样:
$s = '@ABCDEFGHIJKLMNOPQRS';
$s1 = join "", map { $_ | (/[A-I]/ ? "\x80" : "") } split //, $s;
$s2 = join "", map { $_ & "\x7F" } split //, $s1;
或者这个:
$s = '@ABCDEFGHIJKLMNOPQRS';
$s1 = join "", map { $_ = chr((ord $_) | 0x80) if /[A-I]/; $_ } split //, $s;
$s2 = join "", map { chr(ord($_) & ~0x80) } split //, $s1;
或任何其他沿着这些思路的排列。