如何在Ruby中拆分包含集合的字符串?

4

我是一个新来的论坛用户。目前我正在尝试处理这个字符串:

65101km,Sedan,Manual,18131A,FWD,Used,5.5L/100km,Toyota,camry,SE,{AC,Heated Seats, Heated Mirrors, Keyless Entry},2010

并将其分割以获得以下内容:

65101km
Sedan
Manual
18131A
FWD
Used
5.5L/100km
Toyota
camry
SE
{AC, Heated Seats, Heated Mirrors, Keyless Entry}
2010

我有以下正则表达式:

data_from_file.split(/[{},]+/)

但是我很难保持设置。

有什么想法吗?


也许这个答案会有用:https://stackoverflow.com/questions/42475528/split-a-ruby-string-by-colon-except-inside-parenthesis-using-regex 将会有帮助。 - vovan
请确保示例中的所有值都是有效的 Ruby 对象。在这里,这意味着将字符串放在引号中,并将输出显示为字符串数组(["65101km", "Sedan",..., "2010"])。您的意图在这里是清晰的,但如果您的数组是一个输入,那么每个想要在代码中使用它的读者都必须将其转换为有效的对象。此外,在您的示例中为所有输入(仅此一个)分配一个变量(str = "65101km,...")也很有帮助,这样读者就可以在答案和评论中引用这些变量。如果您不知道,您可以为您核对的答案投票。 - Cary Swoveland
2个回答

1
str = "65101km,Sedan,Manual,18131A,FWD,Used,5.5L/100km,Toyota,camry,SE,{AC,Heated Seats, Heated Mirrors, Keyless Entry},2010"

r = /
    (?<=\A|,)  # match the beginning of the string or a comma in a positive lookbehind
    (?:        # begin a non-capture group
      {.*?}    # match an open brace followed by any number of characters,
               # lazily, followed by a closed brace
      |        # or
      .*?      # match any number of characters, lazily 
    )          # close non-capture group
    (?=,|\z)   # match a comma or the end of the string in a positive lookahead
    /x         # free-spacing regex definition mode

str.scan r
  #=> ["65101km", "Sedan", "Manual", "18131A", "FWD", "Used", "5.5L/100km", "Toyota",
  #    "camry", "SE", "{AC,Heated Seats, Heated Mirrors, Keyless Entry}", "2010"]

以下有两个注意事项,我将用一个更简单的字符串来说明。

str = "65101km,Sedan,{AC,Heated Seats},2010"

1. {.*?} 必须在 (?:{.*?}|.*?) 中的 .*? 之前。

如果

r = /(?<=\A|,)(?:.*?|{.*?})(?=,|\z)/

那么

str.scan r
  #=> ["65101km", "Sedan", "{AC", "Heated Seats}", "2010"]

2. 匹配 .* 必须是 懒惰的(也称为非贪婪的

如果

r = /(?<=\A|,)(?:{.*?}|.*)(?=,|\z)/

那么

str.scan r
  #=> ["65101km,Sedan,{AC,Heated Seats},2010"]

如果

r = /(?<=\A|,)(?:{.*}|.*?)(?=,|\z)/

那么

"65101km,Sedan,{AC,Heated Seats},2010,{starter motor, pneumatic tires}".scan r
  #=> ["65101km", "Sedan", "{AC,Heated Seats},2010,{starter motor, pneumatic tires}"]

嗨,Cary,不知道为什么当我把这个放在regex101上时,它没有读取末尾的2010。感谢你的答案! - Andres V.
1
我能说什么呢?Ruby匹配"2010"。你有没有碰巧测试过最后一个逗号和"2010"之间有空格的字符串? - Cary Swoveland
刚试了一下,完美无缺!谢谢大家。我像Gary说的那样加了一个空格。 - Andres V.

1

你可以使用

s.scan(/(?:{[^{}]*}|[^,])+/)

请查看RubularRegex.101演示。

模式细节

  • (?: - 开始一个非捕获组:
    • {[^{}]*} - {,0个或多个非{}字符,然后是}
  • | - 或
    • [^,] - 除,外的任何一个字符
  • )+ - 重复1次或更多次。

1
简单而干净! - Cary Swoveland
1
这真的很好!非常感谢。 - Andres V.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接