2

使用visualworks,在闲聊中,我从网络连接接收到一个类似'31323334'的字符串。

我需要一个读取 '1234' 的字符串,所以我需要一种方法来一次提取两个字符,将它们转换为它们在 ascii 中表示的内容,然后构建它们的字符串......

有没有办法这样做?

编辑(7/24):出于某种原因,你们中的许多人都假设我只会使用数字,并且可以截断 3 或读取每个其他字符。情况并非如此,读取的字符串示例可能包括美国标准键盘上的任何键(az、AZ、0-9、标点符号/注释,例如 {}*&^%$...)

4

3 回答 3

2

遵循 Max 开始建议的内容:

x := '31323334'.
in := ReadStream on: x.
out := WriteStream on: String new.
[ in atEnd ] whileFalse: [ out nextPut: (in next digitValue * 16 + (in next digitValue)) asCharacter ].
newX := out contents.

newX会有结果的'1234'。或者,如果您从以下内容开始:

x := '454647'

你会得到'EFG'.

请注意,digitValue可能只能识别大写十六进制数字,因此asUppercase在处理之前可能需要对字符串进行 an 。

于 2015-07-23T19:24:11.420 回答
0

在 Smalltalk/X 中,有一个fromHexBytes:ByteArray 类可以理解的名为 " " 的方法。我不确定,但认为在其他 ST 方言中也存在类似的情况。

如果存在,您可以通过以下方式解决此问题:

 (ByteArray fromHexString:'68656C6C6F31323334') asString

反过来是:

 'hello1234' asByteArray hexPrintString

另一种可能的解决方案是将字符串读取为十六进制数字,获取 digitBytes(它应该为您提供一个字节数组),然后将其转换为字符串。IE

(Integer readFrom:'68656C6C6F31323334' radix:16)
    digitBytes asString

一个问题是我不确定您将获得哪个字节顺序(LSB 或 MSB),以及是否定义为跨架构相同或在图像加载时转换为使用本机顺序。因此可能需要在末尾反转字符串(为了便于携带,甚至可能需要有条件地反转它,具体取决于系统的字节序。

我无法在 VisualWorks 上对此进行测试,但我认为它在那里也应该可以正常工作。

于 2015-08-15T12:07:17.653 回答
0

通常有一个#fold:or#reduce:方法可以让你做到这一点。在 Pharo 中还有一条消息#allPairsDo:#groupsOf:atATimeCollect:. 使用其中一种方法,您可以:

| collectionOfBytes |
collectionOfBytes := '9798' 
  groupsOf: 2
  atATimeCollect: [ :group |
    (group first digitValue * 10) + (group second digitValue) ].
collectionOfBytes asByteArray asString "--> 'ab'"

Pharo 中的#digitValue消息只是返回数字字符的数字值。

如果您在流上接收数据,则可以#groupsOf:atATime:用循环替换(result可能是您随后转换为上述字符串的任何集合):

...
[ stream atEnd ] whileFalse: [
  result add: (stream next digitValue * 10) + (stream next digitValue) ]
...
于 2015-07-23T04:58:30.513 回答