3

测验问题:

您将获得以下从 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)吗?

4

1 回答 1

3

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

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

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

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

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

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

/"(.*)",\s*"(.*)"/
  1. "(.*)"= 由 .包围的几乎任何字符的任何数字(包括 0)"
  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:"\""> 
于 2013-07-21T23:47:48.833 回答