从smalltalk中的字符串中提取子字符串(squeak)

时间:2014-12-07 14:33:30

标签: oop smalltalk squeak

我试图从字符串中提取子字符串,该字符串将是2个分隔符之间的子字符串 即它应该定义如下:

substring: aString delimiter: aDelimiter

并且,举例来说,如果我得到这一行:

substring: 'dddd#sss#dddd' delimiter: '#'

该功能应该返回' sss'。

这就是我一直在尝试的,但这并不起作用:

substring: aString delimiter: aDelimiter
|index temp1 temp2 sz arr str|
      arr := aString asArray.
      sz := arr size.
      index := arr lastIndexOf: aDelimiter.
      temp1 := arr first: (sz - index +1).
      index := temp1 lastIndexOf: aDelimiter.
      sz :=temp1 size.
      temp2 := temp1 first: (sz - index).
      str := temp2 asString.
      ^str.

我不知道它是否值得一提,但它应该是一种课堂方法。

3 个答案:

答案 0 :(得分:4)

你的基本问题是参数aDelimiter是一个字符串而不是一个字符。你想用$#而不是'#'来调用它。

现在有一些更简单的方法。可能最简单的方法是使用subStrings:方法:

('dddd#sss#dddd' subStrings: '#') at: 2

这样做的缺点是它将整个字符串提取到由#字符分隔的子字符串中,这可能超出了你的需要。

下一个最简单的选择是使用流:

'dddd#sss#dddd' readStream upTo: $#; upTo: $#

该代码仅提取您需要的部分。

答案 1 :(得分:3)

正如大卫所指出的那样,你并没有远离工作代码。但我想指出它非常程序化。 Smalltalk和OOP的许多神奇之处在于编写美观,易于理解的代码,将有意义的消息发送给适当对象的社区。这包括依靠图像中已存在的对象。我无法想象一下,我必须为这样一个简单的任务进入这个低级别。阅读许多令人敬畏的OOP引用之一会很棒。我最喜欢的是A Mentoring Course on Smallalk

我认为大卫的解决方案是正确的。我个人喜欢second而不是at: 2,但它感觉挑剔,可能是个人偏好('dddd#sss#dddd' subStrings: '#') second

答案 2 :(得分:2)

虽然我喜欢上面的两个答案,但您可能还想考虑另一个更接近您的初始尝试,并且比其他人更有效率,因为它只创建您正在寻找的对象(例如,没有中间流)

substringOf: aString delimitedBy: aCharacter
    | i j |
    i := aString indexOf: aCharacter.
    j := aString indexOf: aCharacter startingAt: i + 1.
    ^aString copyFrom: i + 1 to: j - 1

(注意b.t.w.我也建议选择器略有不同。)

您要考虑的另一个方面是,如果aCharacter不在aString中,该方法应该如何反应,它只有一次或者有三次或更多次出现。有些东西:

substringOf: aString delimitedBy: aCharacter
    | i j |
    i := aString indexOf: aCharacter.
    i = 0 ifTrue: [^''].
    j := aString indexOf: aCharacter startingAt: i + 1.
    j = 0 ifTrue: [^''].
    ^aString copyFrom: i + 1 to: j - 1

但是,再次,如果你的情况下表现不是一个问题,那么请去readStream upTo upTo回答,因为它可能是最好的。