这里有三种方法可以做到这一点。
#1 使用正则表达式和捕获组
r = /
\A # match beginning of string
[^[[:alnum:]]]* # match 0+ chars other than digits and lc letters
(\d+) # match 1+ digits in capture group 1
[^[[:alnum:]]]* # match 0+ chars other than digits and lc letters
\z # match end of string
/x # free-spacing regex definition mode
"$ ^*123@-"[r, 1] #=> '123'
"$ ^*123@-a?"[r, 1] #=> nil
"$9^*123@-"[r, 1] #=> nil
#2 使用正则表达式\K
和积极的前瞻
r = /
\A # match beginning of string
[^[[:alnum:]]]* # match 0+ chars other than digits and lc letters
\K # discard all matched so far
\d+ # match 1+ digits
(?=[^[[:alnum:]]]*\z) # match 0+ chars other than digits and lc letters
# in a positive lookahead
/x # free-spacing mode
"$ ^*123@-"[r] #=> '123'
"$ ^*123@-a?"[r] #=> nil
"$9^*123@-"[r] #=> nil
\K
请注意,由于 Ruby 不支持可变长度的lookbehinds ,所以我们不能有一个积极的lookbehinds。
#3 使用更简单的正则表达式和String
方法
def extract(str)
return nil if str =~ /[[:alpha:]]/
a = str.scan(/\d+/)
a.size == 1 ? a.first : nil
end
extract("$ ^*123@-") #=> '123'
extract("$ ^*123@-a?") #=> nil
extract("$9^*123@-") #=> nil