正则表达式:在url字符串的两个斜杠之间对第二个最后一个值进行子串

我有一个像这样的字符串:

http://www.example.com/value/1234/different-value 

我该如何提取1234

注意:最后可能有斜杠:

 http://www.example.com/value/1234/different-value http://www.example.com/value/1234/different-value/ 

 /([^/]+)(?=/[^/]+/?$) 

应该管用。 您可能需要根据您使用的语言对其进行不同的格式化。 例如,在Ruby中,它就是

 if subject =~ /\/([^\/]+)(?=\/[^\/]+\/?\Z)/ match = $~[1] else match = "" end 

使用Javascript:

 var myregexp = /:\/\/.*?\/.*?\/(\d+)/; var match = myregexp.exec(subject); if (match != null) { result = match[1]; } 

适用于你的例子……但我相信它一般都会失败……

Ruby编辑:

 if subject =~ /:\/\/.*?\/.*?\/(.+?)\// match = $~[1] 

确实有效。

使用切片进行位置提取

如果您总是想从URI中提取第4个元素(包括方案),并确信您的数据是常规的,则可以使用Array#slice ,如下所示。

 'http://www.example.com/value/1234/different-value'.split('/').slice 4 #=> "1234" 'http://www.example.com/value/1234/different-value/'.split('/').slice 4 #=> "1234" 

无论是否有斜杠,无论是否在分割后有超过4个元素,以及第四个元素是否始终是严格数字,这都将可靠地工作。 它的工作原理是因为它基于元素在路径中的位置,而不是元素的内容。 但是,如果您尝试使用较少的元素(例如http://www.example.com/1234/解析URI,则最终会得到nil

使用扫描/匹配进行模式提取

或者,如果您知道您要查找的元素始终是唯一一个完全由数字组成的元素,则可以使用String#match with look-arounds来仅提取字符串的数字部分。

 'http://www.example.com/value/1234/different-value'.match %r{(?<=/)\d+(?=/)} #=> # $& #=> "1234" 

需要使用look-behind和look-ahead断言将表达式锚定到路径。 没有它们,你也会匹配像w3.example.com这样的东西。 如果目标元素的位置可能发生变化,并且您可以保证您感兴趣的元素将是唯一与锚定正则表达式匹配的元素,则此解决方案是更好的方法。

如果有多个匹配(例如http://www.example.com/1234/5678/ ),那么您可能希望使用String#scan来选择第一个或最后一个匹配。 这是“了解你的数据”之一; 如果你有不规则的数据,那么正则表达式并不总是最好的选择。

我认为这比接受的答案稍微简单一点,因为它不使用任何正向前瞻( ?= ),而只是简单地使最后一个斜线通过? 字符:

 ^.+\/(.+)\/.+\/?$ 

在Ruby中:

 STDIN.read.split("\n").each do |nextline| if nextline =~ /^.+\/(.+)\/.+\/?$/ printf("matched %s in %s\n", $~[1], nextline); else puts "no match" end end 

现场演示


让我们分解正在发生的事情:

  • ^ :开始行
  • .+\/ :匹配任何东西(贪婪地)到斜线
    • 由于我们稍后将匹配至少1个,最多2个斜杠,此斜杠将是第二个斜杠(如http://www.example.com/value/1234/different-value )或( http://www.example.com/value/1234/different-value/ )中的第三个斜杠
    • 到目前为止,我们已经匹配http://www.example.com/value/ (由于贪婪)
  • (.+)\/ :括号所示的1234捕获组。 接下来是另一个斜线。
    • 由于上一个匹配匹配到第二个或第三个最后一个斜杠,这将分别匹配最后一个斜杠或倒数第二个斜杠
  • .+ :匹配任何东西。 这将是在我们的1234 ,所以我们假设在1234/different-value )之后有字符
  • \/? :可选地匹配另一个斜杠( different-value后面的斜杠)
  • $ :匹配行尾

请注意,在url中,您可能没有空格。 我用了. 字符,因为它很容易区分,但也许您可能使用\S来代替非空格。

此外,您可以使用\A而不是^来匹配字符串的开头(而不是换行符后)和\Z而不是$来匹配字符串的结尾(而不是换行符)