【问题标题】:Consistently separate values in array一致地分隔数组中的值
【发布时间】:2015-05-26 19:39:20
【问题描述】:

上传文件后,我将文件的每一行放入一个数组中。 我只想保存数组的一部分,这里是数组的一个例子...

[ "1, \"Hlavní\"\n", "2, OK\n", "3618, \"Duplicitní záznamy\"\n", "3619, \"Anyth1ng_ Go@es /n th7s'me??\"\n" ]

我想将字符串修剪到...

[ "Hlavní", "OK", "Duplicitní záznamy", "Anyth1ng_ Go@es /n th7s'me??" ]

我可以确定的一件事是它总是在\"\",\n 之间,我试过抓取文本但不知道如何让它如此精确。

这是上传的一个文件:

#INDEX  STRING
0, "Deutsch"
# Main
1, "Hauptmenü"
2, "Sonstiges"
3, "Kontrolle"
4, "Datei Ansicht"
5, "Laden..."
6, "Registriert"
7, "Nicht registriert"
8, "Ja"
9, "Nein"
10, "Anrufen"
11, "Suchen"
12, "Neu"
13, "Bearbeiten"
14, "Löschen"
15, "Alle löschen"
16, "Zurück"
17, "Zurück zum Hauptverzeichnis"
18, "Optionen"
19, "Speichern"

还有一个

#Comment 1-500
1, Ende
2, OK
3, Abbrechen
4, Senden
5, Ja
6, Nein
7, Ein
8, Aus
9, Start
10, Stopp
11, Pause
12, Standard
13, Alle
14, Titel
15, Benutzerdefinierte Sprache

#Call 501-999
501, Telefon
503, Wählen...
504,

【问题讨论】:

  • 看起来您最好向我们展示您在将它们转换为数组之前拥有的字符串/行。与转换您拥有的数组相比,我们可能会给出一个简单的答案。换句话说,这可能是一个 XY 问题。
  • @sawa 好的,这是一个带有回形针的文件附件。你想如何展示它?反正我能不能打开?
  • 如果是 CSV 文件,为什么不直接使用 CSV 库呢? CSV 有点像 PITA;尝试使用正则表达式将其拆开——“现在你有两个问题”。
  • 它是一个纯文本文件,我将发布我用来打开它的代码
  • 在我看来像 CSV,虽然每行只有两个值。不知道为什么你不能把所有的东西都去掉,包括第一个逗号;你需要什么正则表达式?

标签: ruby arrays regex string


【解决方案1】:
[ "1, \"Hlavní\"\n", "2, OK\n", "3618, \"Duplicitní záznamy\"\n", "3619, \"Anyth1ng_ Go@es /n th7s'me??\"\n" ]
.map{|s| s[/(?<=")[^"]*(?=")/]}
# => ["Hlavní", nil, "Duplicitní záznamy", "Anyth1ng_ Go@es /n th7s'me??"]

请注意,根据您的请求,结果中的第二个元素是 nil(提取 \"\" 之间的元素)。

【讨论】:

  • 这适用于 \"。你知道如何从 "2, OK\n" 中获取文本吗?', ' 和 '\n'
  • 我以为你写的元素在\"之间。
  • 是的,一个文件,但其他文件不加引号。所以看起来另一个在字符串的左边有一个',',在右边有一个'\n'。
  • 还是加1,不能忽略更好的答案。
【解决方案2】:

这是一种选择:

arr = [ "1, \"Hlavní\"\n",
        "2, OK\n",
        "3618, \"Duplicitní záznamy\"\n",
        "3619, \"Anyth1ng_ Go@es /n th7s'me??\"\n" ]

r = /,\s+"\K.+?(?=")|,\s+\K.+?(?=\n)/    
arr.map { |s| s[r] }
  #=> ["Hlavní", "OK", "Duplicitní záznamy", "Anyth1ng_ Go@es /n th7s'me??"] 

我要求字符串前面有, \",。前者比规定的匹配要求要强一些;如果不合适,可以以明显的方式削弱它。我使用了\K(匹配前面的内容,但不包含在匹配中)而不是积极的向后看,以允许逗号后有不同数量的空格。

让我们仔细看看正则表达式。通过在末尾添加x ("extended"),我们可以将其串到几行注释中:

r = /
  ,\s+   # match a comma followed by one or more whitespace chars
  "      # match `"`
  \K     # forget what has been matched previously
  .+?    # match any number of any character, lazily
  (?=")  # match must be immediately followed by `"` (positive lookahead)
  |      # match what has been matched so far or is matched later ("or")
  ,\s+   # as above
  \K     # as above
  .+?    # as above
  (?=\n) # match to be immediately followed by `\n` (positive lookahead)
/x

让我们确认正则表达式可以这样写:

arr.map { |s| s[r] }
  #=> ["Hlavní", "OK", "Duplicitní záznamy", "Anyth1ng_ Go@es /n th7s'me??"]

注意:

  • ? 跟随 .+ 使匹配变得懒惰(“非贪婪”),以便在找到匹配的后续元素("\n)时停止,而不是在找到之前吞噬所有内容字符串中的最后一个"\n
  • 两个正向前瞻是“零宽度”,这意味着它们不消耗不属于匹配的字符。

也可以这样写:

arr.map { |s| s[/,\s+\K(?:"\K.+?(?=")|.+?(?=\n))/] }

【讨论】:

【解决方案3】:

我认为选择的答案不是最好的,这里有一个更好的。

@upload = File.new(@request.attachment.path)
@messages = File.read(@upload).scan(/\s+"?([^"\n]*)(?:"|\n)/).flatten

【讨论】:

  • 您的建议可能令人满意,但问题表明它不应该匹配"2, OK\"",而"2, OK\"".scan(/,\s* "?([^"\n]*)(?:"|\n)/).flatten #=&gt; ["OK"]
  • @CarySwoveland 我在问题中没有看到这一点。
  • 我相信'它总是介于 \"\",\n' 意味着'它总是介于 1) \"\" 或 2 之间) ,\n',但你的解释可能是正确的,如果不正确,它可能是令人满意的,或者可能是改进。
猜你喜欢
  • 1970-01-01
  • 2022-08-13
  • 2021-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-26
相关资源
最近更新 更多