ruby 从字符串中删除反斜杠(转义字符)

frebpwbc  于 2023-06-22  发布在  Ruby
关注(0)|答案(5)|浏览(221)

我正在尝试自己的JSON解析器。我有一个要标记的输入字符串:
input = "{ \"foo\": \"bar\", \"num\": 3}"
如何删除转义字符\,使其不再是令牌的一部分?
目前,我使用delete的解决方案可以工作:
tokens = input.delete('\\"').split("")
=> ["{", " ", "f", "o", "o", ":", " ", "b", "a", "r", ",", " ", "n", "u", "m", ":", " ", "3", "}"]
但是,当我尝试使用gsub时,它找不到任何\"
tokens = input.gsub('\\"', '').split("")
=> ["{", " ", "\"", "f", "o", "o", "\"", ":", " ", "\"", "b", "a", "r", "\"", ",", " ", "\"", "n", "u", "m", "\"", ":", " ", "3", "}"]
我有两个问题:

1.为什么gsub在这种情况下不起作用?
2.如何删除反斜杠(转义)字符?我目前必须删除带引号的反斜杠字符,以使其工作。

dz6r00yl

dz6r00yl1#

你的字符串中没有反斜杠。字符串中有引号,当放在双引号字符串中时需要转义。你看:

input = "{ \"foo\": \"bar\", \"num\": 3}"
puts input
# => { "foo": "bar", "num": 3}

你在移除-幽灵。

input.delete('\\"')

将删除其参数中的所有字符。因此,您可以删除任何不存在的反斜杠,并删除所有引号。如果没有引号,默认的显示方法(inspect)将不需要转义任何内容。

input.gsub('\\"', '')

将尝试删除不存在的序列\",因此gsub最终什么也不做。
确保您知道字符串表示(puts input.inspect)和字符串内容(puts input)之间的区别,并注意反斜杠作为表示的工件。
这就是说,我不得不回声emaillenin:编写一个正确的JSON解析器并不简单,你不能用正则表达式(或者至少不能用 * regular * 正则表达式;用Oniguruma可能是可能的)。它需要一个合适的解析器,比如treetop或rex/racc,因为它有很多容易被忽略的特殊情况(具有讽刺意味的是,其中最主要的是转义字符)。

bttbmeg0

bttbmeg02#

input.gsub(/[\"]/,"")也可以工作。

v7pvogib

v7pvogib3#

使用正则表达式模式:

> input = "{ \"foo\": \"bar\", \"num\": 3}"
> input.gsub(/"/,'').split("")

> => ["{", " ", "f", "o", "o", ":", " ", "b", "a", "r", ",", " ", "n", "u", "m", ":", " ", "3", "}"]

这实际上只是一个双引号。斜线是为了逃避它。

oymdgrw7

oymdgrw74#

从原因上讲,为什么会出现这种字符串?
为了以防万一,请检查您的代码是否在Hash或其他东西上重复了to_json方法。

{ "foo": "bar", "num": 3}.to_json #=> { "foo": "bar", "num": 3}
{ "foo": "bar", "num": 3}.to_json.to_json #=> "{ \"foo\": \"bar\", \"num\": 3}"
56lgkhnf

56lgkhnf5#

当你写:

input = "{ \"foo\": \"bar\", \"num\": 3}"

在input中存储的实际字符串是:

{ "foo": "bar", "num": 3}

这里的转义符\"由Ruby解析器解释,因此它可以区分字符串的边界(最左边和最右边的")和字符串中的普通字符"(转义字符)。
String#delete删除第一个参数指定的 * 字符集 *,而不是模式。第一个参数中的所有字符都将被删除。所以通过写作

input.delete('\\"')

你得到的是一个从input中删除了所有\"的字符串,而不是一个从input中删除了所有\"序列的字符串。这不适合你的案子。它可能会在一段时间后导致意外行为。
但是,String#gsub会替换一个模式(正则表达式或普通字符串)。

input.gsub('\\"', '')

查找所有\"(序列中的两个字符)并将其替换为空字符串。由于input中没有\,因此没有替换任何内容。实际上你需要的是:

input.gsub('"', '')

相关问题