【问题标题】:visualworks smalltalk: how can I detect substring from a string, is it possible?visualworks smalltalk:如何从字符串中检测子字符串,有可能吗?
【发布时间】:2020-04-21 18:17:33
【问题描述】:

正如标题所示,我不确定检测字符串中是否存在子字符串的最佳途径,例如:

OverExtended:anErrorMessage

"anErrorMessage = 'error: robot arm extended too far' "

(anErrorMessage **contains:** 'extended too far')
ifTrue:[
   ...
   ...
]
ifFalse:[
   ...
   ...
].

现在我知道上面的方法行不通,但是是否有现有的方法来检查子字符串??

【问题讨论】:

  • 应该注意,传入的文本可以是可变的,所以我不能简单地通过字符索引来查看(即从 18 到:end 等于 'extended too far',因为有些可能在尾部包含更多或前端)
  • 您也可以说出您使用的是哪个版本。总是有帮助的。

标签: string substring smalltalk visualworks


【解决方案1】:

这可能与方言有关,因此请尝试以下操作

'Smalltalk' includesSubstring: 'mall' --> true
'Smalltalk' includesSubstring: 'malta' --> true

'Smalltalk' indexOfSubCollection: 'mall' --> 2
'Smalltalk' indexOfSubCollection: 'malta' --> 0

(见下方 Bob 的评论)

'Smalltalk' indexOfSubCollection: 'mall' startingAt: 1 --> 2
'Smalltalk' indexOfSubCollection: 'malta' startingAt: 1 --> 0

您可能希望将上述其中一项添加到您的图像中,例如

String >> includesString: aString
  ^(self indexOfSubCollection: aString: startingAt: 1) > 0

【讨论】:

  • CharacterArray>>includesSubString: 和 SequenceableCollection>>indexOfSubCollection: 都是 Grease 扩展。但是 CharacterArray>>indexOfSubCollection:startingAt: 是基本大众代码。 VW 确实应该在基本 VW 代码中添加更多类似的实用方法。
  • @BobNemec 谢谢!如果将您的评论添加到我的答案中。
  • 好,但你可能的意思是 (self indexOf...) > 0
  • @aka.nice 谢谢!
【解决方案2】:

试试#match:,就像这样:'*fox*' match: 'there''s a fox in the woods'。有两种通配符:*## 匹配任何单个字符。 * 匹配任意数量的字符(包括无)。

#match: 默认为不区分大小写匹配,如果需要区分大小写,请使用#match:ignoringCase: 并传递false 作为第二个参数。

【讨论】:

    【解决方案3】:

    Match 在 VisualWorks 中运行良好,但我在字符串中添加了一个实用方法:

    includesSubString: aString

    | readStream |
    readStream := self readStream.
    readStream upToAll: aString.
    ^readStream atEnd not
    

    【讨论】:

    • 如果aString出现在receiver末尾怎么办? readStream 也将定位在 atEnd。对吗?
    • @LeandroCaniglia 不,upToAll: 将流定位在下一次出现之前。你一定是在考虑thoughAll:,它会让流超过下一次发生
    • @aka.nice 我不知道它在大众汽车中是如何工作的(这就是我问的原因)。在包括 Pharo 在内的某些方言中,#upToAll: 会在参数之后立即离开该位置(如果找到的话)。因此,如果是这种情况并且参数出现在接收器的末尾,则流将定位为atEnd,并且该方法将失败。如果#upToAll: 在大众汽车中不同,那么上面的代码会按预期工作。
    • @LeandroCaniglia 嗯,你是对的,我以前从未注意到差异!在 Squeak/Pharo/Cuis 中,它使流位于事件之后。 'tic tac toe' readStream upToAll: 'tac'; upToEnd.-> ' toe' 但在大众汽车中是 'tac toe'。在 VW 中,upTo:$c 将流定位在字符 $c 的下一次出现之后,所以 VW 本身可能不是那种逻辑......
    【解决方案4】:

    我找到了一个在所有场景中既简单又准确的答案,不依赖于 readStreams 或早在 VW7.4 的“原始”大众汽车的扩展:

    只需使用 findString:startingAt: 并对出现次数进行大于零的检查

    样本:

    |string substring1 substring2|
    string:= 'The Quick Brown Fox'.
    substring1:= 'quick'.
    substring2:='Quick'.
    
    "below returns FALSE as 'quick' isnt found"
    (string findString: substring1 startingAt:1)>0
    ifTrue:[^'found [quick]'].
    
    "below returns TRUE as 'Quick' is found"
    (string findString: substring2 startingAt:1)>0
    ifTrue:[^'found [Quick]'].
    
    ^'found nothing'.
    

    【讨论】:

      猜你喜欢
      • 2013-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多