Ruby正则表达式非捕获组

Ruby正则表达式非捕获组,ruby,regex,Ruby,Regex,我正试图从字符串中获取id号,比如说 id/number/2000GXZ2/ref=sr 使用 由于某些原因,非捕获组不工作,因此: id/number/2000GXZ2 正如其他人所提到的,非捕获组仍将计入整体比赛。如果你不想在比赛中扮演那个角色,那就用后视。 (?您有: str = "id/number/2000GXZ2/ref=sr" r = / (?:id\/number\/) # match string in a non-capture group ([a-z

我正试图从字符串中获取id号,比如说

id/number/2000GXZ2/ref=sr
使用

由于某些原因,非捕获组不工作,因此:

id/number/2000GXZ2

正如其他人所提到的,非捕获组仍将计入整体比赛。如果你不想在比赛中扮演那个角色,那就用后视。

(?您有:

str = "id/number/2000GXZ2/ref=sr"

r = /
    (?:id\/number\/) # match string in a non-capture group
    ([a-zA-Z0-9]{8}) # match character in character class 8 times, in capture group 1
    /x               # extended/free-spacing regex definition mode
然后(使用):

返回整个匹配,它应该不仅仅是捕获组1的内容。有几种方法可以补救。考虑不使用捕获组的第一个。

@jacob.m建议将第一部分放在积极的lookback中(从他的代码中稍微修改):

\K
在要忘记的匹配是可变长度的情况下特别有用,因为(在Ruby中)正向lookbehind不适用于可变长度匹配

使用这两种方法,如果要匹配的部分仅包含数字和大写字母,则您可能希望使用
[A-Z0-9]+
而不是
[[:alnum:]]
(尽管后者包括Unicode字母,而不仅仅是来自英文字母表的字母)。事实上,如果所有条目都具有您的示例的形式,您可能可以使用:

r = /
    \d          # match a digit
    [A-Z0-9]{7} # match >= 0 capital letters or digits
    /x

str[r]
  #=> "2000GXZ2"
另一种方法是保留捕获组。一种简单的方法是:

r = /
    id\/number\/     # match string
    ([[:alnum:]]{8}) # match >= 1 alphameric characters in capture group 1
    /x

str =~ r
str[r, 1] #=> "2000GXZ2"
或者,您可以使用将整个字符串替换为捕获组的内容:

r = /
    id\/number\/     # match string
    ([[:alnum:]]{8}) # match >= 1 alphameric characters in capture group 1
    .*               # match the remainder of the string
    /x

str.sub(r, '\1')  #=> "2000GXZ2"
str.sub(r, "\\1") #=> "2000GXZ2" 
str.sub(r) { $1 } #=> "2000GXZ2"

这是Ruby
Regexp
预期的匹配一致性问题。一些
Regexp
风格的方法将返回全局匹配,而其他方法将返回指定的匹配

在这种情况下,我们可以使用的一种方法是

我认为这里没有人真正提到如何让您的
Regexp
按照您最初的意图工作,即获得仅捕获匹配。要做到这一点,您可以使用
scan
方法对原始模式进行如下操作:

test\u me.rb

test_string="id/number/2000GXZ2/ref=sr"
result = test_string.scan(/(?:id\/number\/)([a-zA-Z0-9]{8})/)
puts result

也就是说,将
(?:)
替换为
(?您如何获得结果?您需要获取第一个捕获的组非捕获组的目的是在不生成捕获的情况下对内容进行分组,但不是从全局匹配中删除匹配的子字符串。如果您正确获取正则表达式本身不做任何事情,则它会起作用。您如何使用正则表达式?拆分字符串w用它?用它替换字符串的某些部分?你需要从中得到什么:
id/number/2000GXZ2/ref=sr
?(哪部分)哇,谢谢你如此详尽的回答。非常感谢!
r = /
    id\/number\/   # match string
    \K             # forget everything matched so far
    [[:alnum:]]{8} # match 8 alphanumeric characters
    /x

str[r]
  #=> "2000GXZ2"
r = /
    \d          # match a digit
    [A-Z0-9]{7} # match >= 0 capital letters or digits
    /x

str[r]
  #=> "2000GXZ2"
r = /
    id\/number\/     # match string
    ([[:alnum:]]{8}) # match >= 1 alphameric characters in capture group 1
    /x

str =~ r
str[r, 1] #=> "2000GXZ2"
r = /
    id\/number\/     # match string
    ([[:alnum:]]{8}) # match >= 1 alphameric characters in capture group 1
    .*               # match the remainder of the string
    /x

str.sub(r, '\1')  #=> "2000GXZ2"
str.sub(r, "\\1") #=> "2000GXZ2" 
str.sub(r) { $1 } #=> "2000GXZ2"
test_string="id/number/2000GXZ2/ref=sr"
result = test_string.scan(/(?:id\/number\/)([a-zA-Z0-9]{8})/)
puts result
2000GXZ2