【问题标题】:How to split a string that contains a set in Ruby?如何在 Ruby 中拆分包含集合的字符串?
【发布时间】:2019-04-19 19:14:24
【问题描述】:

我是论坛的新手。我目前正在尝试使用这个字符串:

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(/[{},]+/)

但是我很难守住这一套。

有什么想法吗?

【问题讨论】:

  • 也许这个答案会有用:stackoverflow.com/questions/42475528/… 会有所帮助
  • 今后,请确保示例中的所有值都是有效的 Ruby 对象。这意味着将字符串放在引号中并将输出显示为字符串数组 (["65101km", "Sedan",..., "2010"])。在这里,您的意图很明确,但如果您的数组是输入,每个想要在代码中使用它的读者都必须将其转换为有效对象。此外,在您的示例 (str = "65101km,...") 中为所有输入(这里只有一个)分配一个变量也很有帮助,因此读者可以在答案和 cmets 中引用这些变量。如果您不知道,您可以为您勾选的答案投票。

标签: ruby regex split


【解决方案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。匹配 .* 必须是 lazy(又名 non-greedy

如果

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。谢谢你的回答!
  • 我能说什么? Ruby 匹配 "2010"。您是否使用包含最后一个逗号和“2010”之间的空格的字符串进行测试?
  • 刚刚试了一下它的完美!多谢你们。我像加里说的那样放了一个空格。
【解决方案2】:

你可以使用

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

查看RubularRegex.101 演示。

模式详情

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

【讨论】:

  • 简单干净!
  • 这真是太好了!非常感谢
猜你喜欢
  • 2020-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多