给定一个字符串,我想要
A
将foI
的第 8 位开始的所有字符设置为(0x41
~0x49
到0xC1
~0xC9
)。- 将所有第 8 位打开的字符重置为关闭。
喜欢,
$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
, ie ,然后在必要时15
转换为。'15'
那不是你想要的;相反,您对字符串中字符的 ASCII/Unicode/字节值感兴趣。对于此类转换,您需要使用ord
(字符→数字)和chr
(数字→字符)。但你不能写chr(~0x80)
,因为~0x80
是0xFFFFFFFFFFFFFF7F
(假设是 64 位系统),这不是有效的字符代码。相反,您需要编写chr(0x7F)
, 或"\x7F"
,否则应用chr
后面的内容按位运算,通过编写例如chr(ord($_) & ~0x80)
.所以,把它们放在一起,你可以这样写:
或这个:
或任何其他沿着这些思路的排列。
超快速的解决方案: