【问题标题】:Ruby regular expressions for movie titles and ratings电影标题和评级的 Ruby 正则表达式
【发布时间】:2013-07-21 22:22:23
【问题描述】:

测验题:

以下是从 Excel 逗号分隔值 (CSV) 文件导出的电影的简短列表。每个条目都是一个字符串,其中包含双引号中的电影名称、零个或多个空格以及双引号中的电影评级。例如,这是一个包含三个条目的列表:

movies = [
  %q{"Aladdin",  "G"},
  %q{"I, Robot", "PG-13"},
  %q{"Star Wars","PG"}
]

你的工作是创建一个正则表达式来帮助解析这个列表:

movies.each do |movie|
  movie.match(regexp)
  title,rating = $1,$2
end
# => for first entry, title should be Aladdin, rating should be G,
# => WITHOUT the double quotes

您可以假设电影名称和评分从不包含双引号。在单个条目中,在标题后的逗号和评分的开头引号之间可能会出现可变数量的空格(包括 0)。

以下哪个正则表达式可以实现这一点?勾选所有适用的选项。

  1. 正则表达式 = /"([^"]+)",\s*"([^"]+)"/
  2. 正则表达式 = /"(.*)",\s*"(.*)"/
  3. 正则表达式 = /"(.*)", "(.*)"/
  4. 正则表达式 = /(.*),\s*(.*)/

有人能解释一下为什么答案是 (1) 和 (2) 吗?

【问题讨论】:

  • 这不是家庭作业,因为我已经提交了测验并找到了答案。我知道 + 表示 1 或更多,^ 表示不,* 表示 0 或更多。
  • 请参阅meta.stackexchange.com/questions/10811/…,了解为什么适合询问家庭作业。
  • 我的意思不是关于家庭作业部分,而是不用你尝试就解决你所有的家庭作业。在这里写下你知道的和你尝试过的,这样其他人就可以回答你在哪里错过了它。如果您知道 + 是一个或多个字符,而另一个只是从整个单词中选择 1 个字符,那么您已经知道答案了。除了它看起来不像我不给你任何东西。看看那个website link i give you before in replace tab,我给你我的例子。你会知道什么答案是正确的以及为什么这个答案是正确的。
  • 现实生活中,做require 'csv'
  • 好的,我现在明白了,你几乎忘记了编辑前正则表达式中的所有 *,这就是为什么我认为你没有尝试任何东西。因为您可以在编辑前清楚地看到正则表达式 1 和其他 3 之间的区别

标签: ruby regex


【解决方案1】:

有人能解释一下为什么答案是 (1) 和 (2) 吗?

生成的字符串将类似于"Aladdin", "G" 我们来看看正确答案#1:

/"([^"]+)",\s*"([^"]+)"/
  1. "([^"]+)" = 至少一个字符不是 "" 包围
  2. , = 逗号
  3. \s* = 多个空格(包括 0)
  4. "([^"]+)" = 先赞

这正是您将获得的字符串类型。我们来看看上面的字符串:

 "Aladdin",   "G"
#^1       ^2^3^4

现在我们来看第二个正确答案:

/"(.*)",\s*"(.*)"/
  1. "(.*)" = 任意数量(包括 0)的 almost any 字符,由 " 包围。
  2. , = 逗号
  3. \s* = 任意数量的空格(包括 0)
  4. "(.*)" = 见第一点

这是正确的以及以下irb 会话(使用 Ruby 1.9.3)显示:

'"Aladdin",   "G"'.match(/"([^"]+)",\s*"([^"]+)"/) # number 1
# => #<MatchData "\"Aladdin\",   \"G\"" 1:"Aladdin" 2:"G">
'"Aladdin",   "G"'.match(/"(.*)",\s*"(.*)"/) # number 2
# => #<MatchData "\"Aladdin\",   \"G\"" 1:"Aladdin" 2:"G">  

为了完整起见,我将说明为什么第三个和第四个也是错误的:

/"(.*)", "(.*)"/

上面的正则表达式是:

  1. "(.*)" = 由" 包围的几乎任何字符的任意数字(包括 0)
  2. , = 逗号
  3. = 一个空格
  4. "(.*)" = 见第一点

这是错误的,例如,Aladdin 包含多个字符(第一个点),如以下 irb 会话所示:

'"Aladdin",   "G"'.match(/"(.*)", "(.*)"/) # number 3
# => nil 

第四个正则表达式是:

/(.*),\s*(.*)/

这是:

  1. (.*) = 几乎任何字符的任意数字(包括 0)
  2. , = 逗号
  3. \s* = 任意数量(包括 0)的空格
  4. (.*) = 见第一点

这是错误的,因为文本明确指出电影标题不包含任何数量的 " 字符并且用双引号括起来。上面的正则表达式不检查电影标题中是否存在" 以及所需的双引号,接受像"," 这样的字符串(无效),如下irb 会话所示:

'","'.match(/(.*),\s*(.*)/) # number 4
# => #<MatchData "\",\"" 1:"\"" 2:"\""> 

【讨论】:

  • 感谢您的回答!第二个答案应该是正确的,但我无法为 Stack Overflow 获得正确的格式。第二个答案应该有三个星号(在第一个句号之后,在's'之后,在第二个句号之后),但我不知道如何让它们正确显示。
  • 见@Angaa,这是一个答案
  • 抱歉格式错误,感谢您编辑您的答案。我想我也搞砸了第三个正则表达式的星号。我对第二个正则表达式有疑问。我读过星号是贪心的,那.*为什么不在它的末尾加上引号呢?
  • @hdl 在编辑之前看到这个问题正则表达式,以及我对这个问题的最后评论
  • @user86408,再次编辑。因为如果它是正则表达式中的第二个",它将没有匹配项,因此会导致不匹配。
猜你喜欢
  • 2015-01-04
  • 2022-09-28
  • 1970-01-01
  • 1970-01-01
  • 2015-07-20
  • 1970-01-01
  • 2011-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多