【问题标题】:How to Convert a Red/Rebol String into a Series如何将 Red/Rebol 字符串转换为系列
【发布时间】:2015-07-19 21:44:39
【问题描述】:

我想知道是否有办法将字符串转换为系列。我正在尝试使用解析来提取数据,并且我想将一些捕获的数据分解成更小的片段,以便我可以执行 IF、CASE 或 SWITCH 语句。

下面是一段代码。

; A line of text with simple markup
current-line: {[chapter 1] The Wanderer}

; Parse the current line of input
parse current-line [
  "["
  copy tag to "]"
  skip
  copy rest-of-line to end
]

; Just some output to see if i captured data properly
print ["Extracted: " tag]
print ["Rest of line: " rest-of-line]

; The statements below both execute
; but the second one definitely shouldn't execute.
if [find tag  "chapter"] [print "The tag is chapter."]
if [find tag  "list"]    [print "The tag is list."]

据我了解,“查找”适用于系列,这可能是那些 if 语句没有给出我期望的结果的原因。然而,变量“tag”只是一个字符串。

有没有办法将字符串转换为系列?或者是否有任何函数可以在字符串上查找子字符串?

【问题讨论】:

    标签: string block series rebol red


    【解决方案1】:

    下面的语句都执行,但第二个绝对不应该执行。

    if [find tag  "chapter"] [print "The tag is chapter."]
    if [find tag  "list"]    [print "The tag is list."]
    

    这是一个非常常见的新用户问题,可以理解。

    要记住关于 BLOCK 的关键事项!一个块是“只是数据”,除非您(或您调用的函数)通过​​使用 DO 执行它“使该块栩栩如生”。查看 IF 的帮助:

    >> help if
    
    USAGE:
        if cond then-blk
    
    DESCRIPTION:
        If condition is true, evaluate block; else return NONE.
        if is of type: native!
    
    ARGUMENTS:
        cond [any-type!]
        then-blk [block!]
    

    您必须将 THEN-BLOCK 作为值传入,因为它是否会“复活”并由 IF 运行取决于条件是否为真。 IF 必须决定是否执行该阻止。

    但是 IF 的第一个参数是条件。无论条件最终是真还是假,每次命中 IF 语句时都必须运行它。因此,条件上没有块的“样板”。这种样板的缺乏意味着如果你将一个块作为数据传递给它,那么问题就归结为“一个数据块,被视为一个值,是真还是假?”嗯……是真的:

    >> true? [some arbitrary block]
    == true
    

    事实上,所有值都被认为是“有条件地为真”,除了 NONE!价值或逻辑!错误的。即使是零也是正确的:

    >> if 0 [print "Almost absolutely every value is true!"]
    
    Almost absolutely every value is true! 
    

    因此,您不想将您的条件放在方括号中。要么将其关闭,要么您可以使用括号块“组”。括号确实会评估,但会隔离评估的部分,这可以帮助您隔离子表达式以用于优先级或参数检查等目的。所以:

    if find tag "chapter" [print "The tag is chapter."]
    if (find tag "list") [print "The tag is list."]
    

    希望这有点道理,但您始终必须考虑评估模型才能了解使用或不使用块的动机。例如,WHILE 循环与 IF 不同,因为它需要多次运行条件。

    >> x: 0
    >> while x < 2 [ 
        print x 
        x: x + 1 
    ]
    
    *** Script error: while does not allow logic for its cond argument
    

    当定义 WHILE 时,它必须为条件占用一个块。因为否则 WHILE 函数会将其第一个参数评估为 TRUE,然后每次循环都没有 x &lt; 2 表达式来评估。所以:

    >> x: 0
    >> while [x < 2] [ 
        print x 
        x: x + 1 
    ]
    
    0
    1
    

    你很可能会犯错;如果将 WHILE 转换为 IF,则特别容易做到这一点。然而,尽管 IF 可以 被设计为在其条件 周围强制执行样板代码块(即使对于一次评估条件的东西来说没有必要),反击不必要的样板是系统的目标之一。

    好消息是它背后有一个逻辑和规则......一旦掌握,您就可以使用它来制作自己的循环结构等等。 “疯了,不过是有办法的。” :-)

    我想知道是否有办法将字符串转换为系列。 我正在尝试使用解析来提取数据,我想打破其中的一些 将数据捕获到更小的片段中,以便我可以执行 if、case 或 switch 语句。

    按照今天的术语(在某些其他情况下可能会有点混乱),字符串!已经是SERIES的一员了!排版。也就是说,您可以执行诸如使用 FIRST 或 SECOND 从中挑选元素,或使用 NEXT 遍历它等操作。这就是 SERIES。

    【讨论】:

      【解决方案2】:

      在 Rebol 中,字符串!是系列的一个子类型!所以任何适用于系列的东西!将接受一个字符串!:

      >> X: {Foo}
      == "Foo"
      >> type? X
      == string!
      >> series? X
      == true
      
      >> find X {o}
      == "oo"
      

      'if 的第一个参数被视为一个逻辑!,但你是在一个块中传递! - 这永远是真的:

      >> to-logic []
      == true
      

      您要做的是在将 find 传递给 if 之前对其进行评估。只需删除[]

      if find tag  "chapter" [print "The tag is chapter."]
      if find tag  "list"    [print "The tag is list."]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-04-30
        • 1970-01-01
        • 1970-01-01
        • 2011-03-11
        • 2021-06-16
        • 1970-01-01
        • 2016-03-13
        • 1970-01-01
        相关资源
        最近更新 更多