我正在尝试匹配各种形式的编写操作系统名称。我想在开头匹配一个字符串,第一个数字,如果最后两个字符是" \ d",抓住那个。 例如,给定字符串" Oracle Enterprise Linux 5-X86_64 9",我想匹配" Oracle"," 5"和" 9&# 34 ;. 我试过了:
oracle[ a-z]* ([0-9])(?:.* )*?([0-9])$
但匹配整个字符串
oracle[ a-z]* ([0-9])(?:.)*?([0-9])$
但这也匹配所有内容
oracle[ a-z]* ([0-9]).*?( [0-9])$
同样的结果
为什么" $"不强迫它匹配我想要的字符串?
答案 0 :(得分:2)
有关
str = "Oracle Enterprise Linux 5-X86_64 9"
你说那个
r = /oracle[ a-z]* ([0-9])(?:.* )*?([0-9])$/i
“匹配整个字符串”(我在末尾添加了i
)。如
str[r]
#=> "Oracle Enterprise Linux 5-X86_64 9"
我们认为这是真的,但我们想要的是捕获组的内容。
$1 #=> "5"
$2 #=> "9"
如您所见,您只是忽略了在开头捕捉这个词。因此,你可以这样写正则表达式。 (我做了一些细微的改进。)
r = /
(\p{L}+) # match one or more letters in capture group 1
\D* # match zero or more characters other than digits
(\d) # match a digit in capture group 2
.+ # match one or more characters
(\d+) # match one or more digits in capture group 3
\z # match the end of the string
/x # free-spacing regex definition mode
str.match(r)
$1 #=> "Oracle"
$2 #=> "5"
$3 #=> "9"
方法String#scan提供了一种更好的方法来提取所需的字符串。 (请参阅文档,了解该方法如何处理捕获组。)
str.scan(r).first
#=> ["Oracle", "5", "9"]
答案 1 :(得分:0)
这对我有用:
irb(main):009:0> "Oracle Enterprise Linux 5-X86_64 9".match(/^(Oracle )[^\d]+(\d+).*(\d+$)/i)
=> #<MatchData "Oracle Enterprise Linux 5-X86_64 9" 1:"Oracle " 2:"5" 3:"9">
(Oracle )[^\d]+(\d+).*(\d+$)