gpt4 book ai didi

ruby - 在 ruby​​ String#scan 方法中向正则表达式添加括号会破坏它

转载 作者:数据小太阳 更新时间:2023-10-29 08:26:57 24 4
gpt4 key购买 nike

我有一个使用 ruby​​ 1.8.6 和 rails 2.2.2 的应用程序(请不要谈论我需要如何更新它)。

我有一个服务器访问的文本文档,我正在从中抓取数据。线条就像

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\""

我用这个正则表达式收集了第一个路径部分:

#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"

到目前为止一切顺利。但是有些行将 HEAD 作为方法,所以我修改了我的正则表达式以说 (GET|HEAD) 而不是 GET。现在,它只返回方法名称(GET 或 HEAD),没有路径。例如

path = line1.scan(/\"(GET|HEAD)\s[^\s]+/).first
=> ["GET"]

现在我得到一个数组,而不是一个字符串:扫描的结果(没有先调用,是一个二维数组:

path = line1.scan(/\"(GET|HEAD)\s[^\s]+/)
=> [["GET"]]

我不明白为什么这不起作用。这是扫描方法的特点吗?任何人都可以让我直截了当吗?谢谢

编辑使用 String#match 而不是 #scan 似乎可行:

path = line1.match(/\"(GET|HEAD)\s[^\s]+/).to_s
=> "\"GET /assets/dvd_files/pdfs/4139/DSB%20Guitar%20%E2%80%94%20medium.pdf"

谁能解释为什么匹配有效而扫描无效?

最佳答案

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"]]

(一个匹配中有两个捕获组)。

修复

The documentation指出:

If the pattern contains no groups, each individual result consists of the matched string, $&. If the pattern contains groups, each individual result is itself an array containing one entry per group.

如果你想把 GET|HEAD 括在圆括号中,但又不想让它被认为是一个捕获组,使用 ?:,如下: /(?:GET|HEAD)\s[^\s]+/。这将告诉 Regex 引擎括号只是包含表达式的一部分,但它不是捕获组。

它正在运行:http://ideone.com/0Ri1Uv

关于ruby - 在 ruby​​ String#scan 方法中向正则表达式添加括号会破坏它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27485627/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com