Ruby正则表达式 - 使用可选的命名反向引用

时间:2014-01-31 01:30:24

标签: ruby regex

我正在尝试编写一个返回一组命名匹配的Ruby正则表达式。如果在字符串后面的任何地方找到第一个元素(由斜杠定义),那么我希望匹配返回第二个匹配。否则,返回整个字符串。我得到的最接近的是(?<p1>top_\w+).*?(?<hier>\k<p1>.*),这对第3项不起作用。我已经尝试了正则表达式,如果 - 其他构造,但Rubular说这是无效的。我已经尝试(?<p1>[\w\/]+?)(?<hier>\k<p1>.*)正确分割第1行和第4行,但不适用于其他行。请注意:我希望所有结果都作为相同的命名引用返回,因此我可以遍历“hier”。

输入:

top_cat/mouse/dog/top_cat/mouse/dog/elephant/horse
top_ab12/hat[1]/top_ab12/hat[1]/path0_top_ab12/top_ab12path1/cool
top_bat/car[0]
top_2/top_1/top_3/top_4/top_2/top_1/top_3/top_4/dog

输出:

hier = top_cat/mouse/dog/elephant/horse
hier = top_ab12/hat[1]/path0_top_ab12/top_ab12path1/cool
hier = top_bat/car[0]
hier = top_2/top_1/top_3/top_4/dog

2 个答案:

答案 0 :(得分:1)

问题

它与第二行不匹配的原因是因为第二个hat实例并没有以斜杠结尾,而是第一个实例。

解决方案

指定第一个和第二个匹配之间有斜杠

正则表达式

(top_.*)/(\1.*$)|(^.*$)

替换

hier = \2\3

实施例

Regex101 Permalink


有关轮换令牌的更多信息

要解释|令牌在正则表达式中的工作原理,请参阅示例:abc|def
这个正则表达式用简单的英语表示的是:

  • 匹配下面的正则表达式(仅在此失败的情况下尝试下一个选项)
    • 按字面匹配字符abc
  • 或匹配下方的正则表达式(如果此匹配失败,整个匹配尝试将失败)
    • 按字面匹配字符def

示例
正则表达式:alpha|alphabet
如果我们有一个短语“我知道字母表”,则只会匹配单词alpha 但是,如果我们将正则表达式更改为alphabet|alpha,我们将匹配alphabet

所以你可以看到,轮换以从左到右的方式运作。

答案 1 :(得分:1)

paths = %w(
  top_cat/mouse/dog/top_cat/mouse/dog/elephant/horse
  top_ab12/hat/top_ab12/hat[1]/path0_top_ab12/top_ab12path1/cool
  top_bat/car[0]
  top_2/top_1/top_3/top_4/top_2/top_1/top_3/top_4/dog
  test/test
)

paths.each do |path|
  md = path.match(/^([^\/]*).*\/(\1(\/.*|$))/)
  heir = md ? md[2] : path
  puts heir
end

输出:

top_cat/mouse/dog/elephant/horse
top_ab12/hat[1]/path0_top_ab12/top_ab12path1/cool
top_bat/car[0]
top_2/top_1/top_3/top_4/dog
test