我有一个使用ruby 1.8.6和rails 2.2.2的应用程序(请不要谈论我需要如何更新).
我有一个服务器访问的文本doc,我正在从中抓取数据.线条就像
line1 = "93.97.151.194 - - [14/Nov/2013:20:13:30 +0000] \"GET /assets/dvd_files/pdfs/4139/DSB%20Guitar%20%E2%80%94%20medium.pdf HTTP/1.1\" 200 21172 \"http://www.mysite.co.uk/c/1267-ks3/131936-inspira-pops/134541-don-t-stop-believin-\" \"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36\""
line2 = "93.97.151.194 - - [14/Nov/2013:20:13:30 +0000] \"HEAD /assets/dvd_files/pdfs/4139/DSB%20Guitar%20%E2%80%94%20medium.pdf HTTP/1.1\" 200 21172 \"http://www.mysite.co.uk/c/1267-ks3/131936-inspira-pops/134541-don-t-stop-believin-\" \"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36\""
Run Code Online (Sandbox Code Playgroud)
我用这个正则表达式收集了第一个路径部分:
#this works fine for the GET case
path = line1.scan(/\"GET\s[^\s]+/).first
=> "\"GET /assets/dvd_files/pdfs/4139/DSB%20Guitar%20%E2%80%94%20medium.pdf"
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但是有些行有HEAD作为方法,所以我修改了我的正则表达(GET|HEAD)而不仅仅是GET.现在,它只返回方法名称(GET或HEAD),没有路径.例如
path = line1.scan(/\"(GET|HEAD)\s[^\s]+/).first
=> ["GET"]
Run Code Online (Sandbox Code Playgroud)
现在我得到一个数组,而不是一个字符串:扫描的结果(没有先调用,是一个二维数组:
path = line1.scan(/\"(GET|HEAD)\s[^\s]+/)
=> [["GET"]]
Run Code Online (Sandbox Code Playgroud)
我不明白为什么这不起作用.这是扫描方法的特点吗?谁能让我直截了当?谢谢
编辑使用String #matre而不是#scan似乎工作:
path = line1.match(/\"(GET|HEAD)\s[^\s]+/).to_s
=> "\"GET /assets/dvd_files/pdfs/4139/DSB%20Guitar%20%E2%80%94%20medium.pdf"
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释为什么匹配工作和扫描不在这里?
String#scan 将返回一个匹配数组,其中每个匹配项是一个数组,包含该匹配项的所有捕获组的值.
在Regex中,捕获组是括在括号中的表达式.
在您的情况下,因为您(GET|HEAD)在表达式中,这被认为是捕获并被返回.
为了说明这一点,让我们修改正则表达式/(GET|HEAD)\s([^\s]+)/(我也将该[^\s]+部分设为捕获组).对于您的line1变量,这将返回:
[["GET", "/assets/dvd_files/pdfs/4139/DSB%20Guitar%20%E2%80%94%20medium.pdf"]]
Run Code Online (Sandbox Code Playgroud)
(一个匹配两个捕获组).
文件指出:
如果模式不包含组,则每个单独的结果由匹配的字符串$&组成.如果模式包含组,则每个单独的结果本身就是一个数组,每个组包含一个条目.
如果您希望GET|HEAD括在括号中,但不希望它被视为捕获组,请使用?:,如下所示:/(?:GET|HEAD)\s[^\s]+/.这将告诉Regex引擎括号只是包含表达式的一部分,但它不是捕获组.
在这里它是行动:http://ideone.com/0Ri1Uv
| 归档时间: |
|
| 查看次数: |
425 次 |
| 最近记录: |