我试图从字符串中获取ID号,比如说
id/number/2000GXZ2/ref=sr
使用
(?:id\/number\/)([a-zA-Z0-9]{8})
由于某些原因,非捕获组不起作用,给我:
id/number/2000GXZ2
答案 0 :(得分:9)
正如其他人所提到的,非捕获群体仍然计入整体匹配。如果你不想在你的比赛中使用这个部分,请使用lookbehind。 Rubular example
(?<=id\/number\/)([a-zA-Z0-9]{8})
(?&lt; = pat) - 正向后观断言:确保前面的字符匹配pat,但不包括匹配文本中的那些字符
此外,在这种情况下,id号码周围的捕获组是不必要的。
答案 1 :(得分:2)
你有:
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
然后(使用String#[]):
str[r]
#=> "id/number/2000GXZ2"
应该返回整个匹配,而不仅仅是捕获组1的内容。有几种方法可以解决这个问题。首先考虑不使用捕获组的那些。
@ jacob.m建议将第一部分放在正面看后面(稍微修改一下):
r = /
(?<=id\/number\/) # match string in positive lookbehind
[[:alnum:]]{8} # match >= 1 alphameric characters
/x
str[r]
#=> "2000GXZ2"
另一种选择是:
r = /
id\/number\/ # match string
\K # forget everything matched so far
[[:alnum:]]{8} # match 8 alphanumeric characters
/x
str[r]
#=> "2000GXZ2"
当忘记的匹配是可变长度时, \K
特别有用,因为(在Ruby中)正向外观不适用于可变长度匹配。
使用这两种方法,如果要匹配的部分仅包含数字和大写字母,您可能需要使用[A-Z0-9]+
而不是[[:alnum:]]
。实际上,如果所有条目都具有您的示例的形式,您可以使用:
r = /
\d # match a digit
[A-Z0-9]{7} # match >= 0 capital letters or digits
/x
str[r]
#=> "2000GXZ2"
如果要匹配的子字符串后面总是后跟非字母数字字符,则可以将{8}
替换为+
,将{7}
替换为*
。
另一种方法是保留捕获组。一个简单的方法是:
r = /
id\/number\/ # match string
([[:alnum:]]{8}) # match >= 1 alphameric characters in capture group 1
/x
str =~ r
$1 #=> "2000GXZ2"
或者,您可以使用String#sub将整个字符串替换为捕获组的内容:
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"
答案 2 :(得分:0)
这是Ruby Regexp
预期的匹配一致性恶意。一些Regexp
- 样式方法将返回全局匹配,而其他方法将返回指定的匹配。
在这种情况下,我们可以使用一种方法来获取您正在寻找的行为scan
。
我认为这里没有人真正提到如何让你的Regexp
以你最初的意图工作,这是为了获得仅限捕获的匹配。要做到这一点,您可以使用原始模式的scan
方法:
<强> test_me.rb 强>
test_string="id/number/2000GXZ2/ref=sr"
result = test_string.scan(/(?:id\/number\/)([a-zA-Z0-9]{8})/)
puts result
2000GXZ2
也就是说,当您使用(?:)
以及使用{的其他ruby部分时,使用(?<=)
替换为非捕获组的scan
会使您受益匪浅1}} S上。