使用正则表达式检测版本号的具体格式

问题描述:

我正在寻找提取包含版本号的数组元素,其中版本号是在字符串的开始或结尾或由空格填充,并且是一系列数字和句点,但不以句号开始或结束。例如“10.10 Thingy”和“Thingy 10.10.5”是有效的,但“无论4”不是。使用正则表达式检测版本号的具体格式

haystack = ["10.10 Thingy", "Thingy 10.10.5", "Whatever 4", "Whatever 4.x"] 
haystack.select{ |i| i[/(?<=^|)(\d+)(\.\d+)*(?=$|)/] } 
=> ["10.10 Thingy", "Thingy 10.10.5", "Whatever 4"] 

我不知道如何修改正则表达式来至少需要一个周期,使得“无论4”的结果是没有的。

这只是Archonic的答案的一个轻微变体。

r =/
    (?<=\A|\s) # match the beginning of the string or a space in a positive lookbehind 
    (?:\d+\.)+ # match >= 1 digits followed by a period in a non-capture group, >= 1 times 
    \d+  # match >= 1 digits 
    (?=\s|\z) # match a space or the end of the string in a positive lookahead 
    /x   # free-spacing regex definition mode 

haystack = ["10.10 Thingy", "Thingy 10.10.5", "Whatever 4", "Whatever 4.x"] 

haystack.select { |str| str =~ r } 
    #=> ["10.10 Thingy", "Thingy 10.10.5"] 

问题不在于返回版本信息,而是为了返回具有正确版本信息的字符串。其结果是没有必要的lookarounds:

r =/
    [\A\s\] # match the beginning of the string or a space 
    (?:\d+\.)+ # match >= 1 digits followed by a period in a non-capture group, >= 1 times 
    \d+  # match >= 1 digits 
    [\s\z]  # match a space or the end of the string in a positive lookahead 
    /x   # free-spacing regex definition mode 

haystack.select { |str| str =~ r } 
    #=> ["10.10 Thingy", "Thingy 10.10.5"] 

假设有人想同时获得包含有效的版本字符串和包含在这些字符串的版本。可以写下面的内容:

r =/
    (?<=\A|\s\) # match the beginning of string or a space in a pos lookbehind 
    (?:\d+\.)+ # match >= 1 digits then a period in non-capture group, >= 1 times 
    \d+   # match >= 1 digits 
    (?=\s|\z) # match a space or end of string in a pos lookahead 
    /x   # free-spacing regex definition mode 

haystack.each_with_object({}) do |str,h| 
    version = str[r] 
    h[str] = version if version 
end 
    # => {"10.10 Thingy"=>"10.10", "Thingy 10.10.5"=>"10.10.5"} 
+0

感谢您的详细信息! – Archonic

啊哈!我知道我很亲密。

haystack.select{ |i| i[/(?<=^|)(\d+)(\.\d+)+(?=$|)/] }

(\.\d+)*末尾的星号被允许该图案以重复任何次数,包括零次。你可以用(\.\d+){x,y}来限制它,其中x和y是最小和最大时间。您也只能通过(\.\d+){x,}来确定最小值。在我的情况下,我想要至少一次,这将是(\.\d+){1,},但这是(\.\d+)+的代名词。这只花了一天的时间才能发现......