如何查找与Rebol中的模式匹配的所有子字符串

时间:2014-06-03 22:00:15

标签: regex rebol

在这里,我试图在字符串中找到模式的所有匹配项:

theString: "There is a blue truck and a red car next to an orange building."
thePattern: [["blue" | "red" | "orange"] ["truck" | "car" | "building"]]
print parse thePattern theString

["red truck" "blue car" "orange building"]函数不返回parse,而是返回false

Rebol是否有任何可用于查找字符串中模式匹配的函数,类似于其他编程语言的正则表达式匹配函数?

4 个答案:

答案 0 :(得分:6)

你可以试试这个:

string: "There is a blue truck and a red car next to an orange building."
pattern: [
    ["blue" | "red" | "orange"] 
    space
    ["truck" | "car" | "building"]
]

parse string [
    some [
        copy value pattern (print value)
    |   skip    
    ]
]

打印:

blue truck
red car
orange building
当模式不匹配时,

skip用于移动到下一个字符。此外,空间也被添加到模式中,因为它不是" bluetruck"或者" redcar"。

括号用于在解析规则中执行Rebol代码,因此您可以将print替换为其他内容(如append block value等)。

答案 1 :(得分:2)

在这方面,语言已经在Rebol的Parse上有所改进:

parse "There is a blue truck and a red car next to an orange building." [
    collect [
        some [
            keep [
                ["blue" | "red" | "orange"]
                " "
                ["truck" | "car" | "building"]
            ]
            | skip
        ]
    ]
]

== ["blue truck" "red car" "orange building"]

虽然还没有为黄金时段做好准备,但Red已经暗示了Rebol当前功能集之外的进展。

答案 2 :(得分:2)

  

Rebol是否有任何可用于查找字符串中模式匹配的函数,类似于其他编程语言的正则表达式匹配函数?

已经有了很好的答案。我会指出你可以迭代地使用FIND,如果你想要的是一个精确匹配开始的系列位置,而不是提取它:

foo: "The quick brown quick jumped over the lazy quick"
while [foo: find foo "quick"] [
   print foo
   foo: next foo
] 

你会得到:

quick brown quick jumped over the lazy quick
quick jumped over the lazy quick
quick

作为对PARSE普遍性的另一种了解,我会重申你之所以错误,是因为你的匹配规则是:

[["blue" | "red" | "orange"] ["truck" | "car" | "building"]]

没有重复原语(例如SOME或ANY),它缺少任何跳过事物的方法。因此,它只匹配一个看起来像bluetruckredcarorangebuilding的孤立字符串。它基本上期望第一组中的某些东西直接序列,然后是第二组之外的东西。

解析的具体操作模型是在系列的开头有一个“解析位置”,并且根据规则的匹配方式移动(或不移动)。如果发生规则匹配的结束且解析位置在输入系列的末尾,则返回TRUE。如果规则应用程序完成且您没有结束,则会收到FALSE。

通过混合普通的Rebol代码(嵌入括号)并使用set-words或get-words保存/设置解析位置,你几乎可以做任何事情。

theString: "There is a blue truck and a red ugly car next to an orangebuilding." 
theResult: copy []
thePattern: [
    any [
        to ["blue" | "red" | "orange"]
        start:
        thru ["truck" | "car" | "building"]
        finish:
        (
            append theResult copy/part start finish
        )
     ]
]
parse theString thePattern
probe theResult

那会得到你:

["blue truck" "red ugly car" "orangebuilding"]

当你可以解决问题而不需要像这样破解代码时,这很好 - 通常你可以。但是在你需要时可以选择。

另请注意,为字符文字定义了space,我更喜欢在代码中看到" " ...如果您必须向后查找,这可能具有破坏性一个字符串的开头并向前找到另一个字符串的结尾。值得额外的两个角色!

答案 3 :(得分:1)

不幸的是,这只适用于Rebol3。使用Rebol2,这更复杂。

theString: "There is a blue truck and a red car next to an orange building."

thePattern: [
  copy color   ["blue" | "red" | "orange"] 
   #" "
  copy item  ["truck" | "car" | "building"] 
]

collect [parse/all theString [
  some [ thePattern (keep rejoin [color " " item])  |   skip ]   
] ] 

给出

== ["blue truck" "red car" "orange building"]