在红宝石中,这个正则表达式做了什么? /((\ w)的\ 2 *)/

时间:2015-01-03 00:25:43

标签: ruby regex

"aaabbcde".scan(/((\w)\2*)/)

这行代码将得到如下结果

[["aaa", "a"], ["bb", "b"], ["c", "c"], ["d", "d"], ["e", "e"]]

我不理解的部分是\2*的作用。为什么这会生成一个二维数组?

编辑:

在得到帮助和做一些研究之后,只是我理解的摘要。希望这可以帮助任何搜索类似主题的人。

您可以使用正则表达式创建捕获组。后一组可以参考前面的组。 每个括号都是一个捕获组。因此,如果您执行此操作/(\w)/,则创建一个组,它将提取所有单词字符,并将每个单个字符放入单个组中。

所以你会用字符串"rubyy"

得到这样的东西
Match 1
1.  r
Match 2
1.  u
Match 3
1.  b
Match 4
1.  y
Match 5
1.  y

要创建第二个捕获组,您只需添加另一对括号,例如/((\w))/。但请注意,外部括号是第一组,内部是第二组。这可以来回走。

给定相同的字符串"rubyy",这将产生这样的结果。

Match 1
1.  r
2.  r
Match 2
1.  u
2.  u
Match 3
1.  b
2.  b
Match 4
1.  y
2.  y
Match 5
1.  y
2.  y

您可以尝试将正则表达式更改为/(()\w)//(\w)()/并查看发生的情况(记得我刚才说内部括号是第二组?)。 http://www.rubular.com是在红宝石中试验正则表达式的好地方。

指向另一个捕获组的指针: 所以我最初询问的正则表达式是/((\w)\2*)/\2这部分只是意味着"给我从组#2得到的东西(内部组是#2组),然后把它放进去组#1(外部组,\2是)。那么*只是一个常规正则表达式,意味着零或更多。在这种情况下,#2提取的组中零个或多个。

基于上述理解,您可以尝试执行此操作/(\w)(\1*)/。这也将实现类似的目标。但你应该尝试差异。请记住,/(\2*)(\w)/无法正常工作,因为我猜ruby在这种类型的并行结构中运行顺序运行,因此\2指向尚未存在的捕获组。

2 个答案:

答案 0 :(得分:3)

你有两个捕获组,第一个是((\w)\2*),是从左到右解析时遇到的第一个,第二个是(\w)\2*匹配捕获组#2的结果,零次或多次。

对于"aaa",内部捕获组(#2)与第一个"a"匹配,然后\2*变为a*,与下一个a匹配'第因此,第一个捕获组匹配'aaa'

请注意,捕获组#2始终只匹配一个字符。

答案 1 :(得分:0)

考虑以下

  • //内的任何内容都是匹配
  • 的正则表达式模式
  • \2是一个变量(称为反向引用),指向第二组括号中匹配的任何内容,在本例中为\w。如果它在另一个括号中匹配,则您使用\3;这些未转义的括号称为捕获组
  • *是0或更多匹配

有关正则表达式的任何指南,请参阅任何有关正则表达式的指南。例如:http://www.regular-expressions.info/refcapture.html