1

I have issues using gsub to remove [] and \" from a string. Here is the string:

"[\"This is a word ect\", \"Char2\", \"Another grooup\", \"Char4\"]"

I want the returned value to be:

"This is a word ect, Char2, Another grooup, Char4"

Can anyone point me in the right direction?

sawa
  • 165,429
  • 45
  • 277
  • 381
DMH
  • 2,529
  • 3
  • 24
  • 35

5 Answers5

8

Just out of curiosity:

str = '["This is a word ect", "Char2", "Another grooup", "Char4"]'
require 'json'
JSON.parse(str).join(', ')
#⇒ "This is a word ect, Char2, Another grooup, Char4"
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
  • How come you blocked my edit? It wasn't really a message to you, it was an improvement to your answer. If you didn't think this was the correct solution it should really be made into a comment instead, though this is the correct answer, it needs more explanation so the OP can understand why. – Ninjaxor Apr 29 '15 at 22:40
3

You can use gsub:

=> %Q|"[\"This is a word ect\", \"Char2\", \"Another grooup\", \"Char4\"]"|
=> s.gsub(/"|\[|\]/, '')
=> "This is a word ect, Char2, Another grooup, Char4"

gsub for me " or [ or ].

| - or operator.

\ - escape [ and ]

Roman Kiselenko
  • 43,210
  • 9
  • 91
  • 103
  • sorry I didnt add info that on occasions inside there may be groups of characters as well. Iv edited the question. – DMH Apr 29 '15 at 15:36
1

You can use regex for that:

a = '"["Char1", "Char2", "Char3", "Char4"]"'
a.scan(/[a-zA-Z0-9]+/)
# => ["Char1", "Char2", "Char3", "Char4"]

After Question Edit:

a = '"[\"This is a word ect\", \"Char2\", \"Another grooup\", \"Char4\"]"'
a.split('\"').find_all { |a| a =~ /\w+/ }
# => ["This is a word ect", "Char2", "Another grooup", "Char4"]
shivam
  • 16,048
  • 3
  • 56
  • 71
  • sorry I didnt add info that on occasions inside there may be groups of characters as well. Iv edited the question. – DMH Apr 29 '15 at 15:36
1

Parsing the data with JSON is a safe and effective approach when the data is known to be well formed and parsable:

str = "[\"This is a word ect\", \"Char2\", \"This Element uses a (\\\") symbol that is important to keep\", \"Char4\"]"
require 'json'
JSON.parse(str).join(', ')
 => "This is a word ect, Char2, This Element uses a (\") symbol that is important to keep, Char4"

Otherwise a gsub solution using either regex or simple method chaining can be employed, but this sort of naive approach may remove quotation marks and brackets from the inner elements of the array string being parsed, potentially mangling the data you meant to extract.

str = "[\"This is a word ect\", \"Char2\", \"This Element uses a (\\\") symbol that is important to keep\", \"Char4\"]"
str.gsub('"', '').gsub('[','').gsub(']','')
 => "This is a word ect, Char2, This Element uses a (\\) symbol that is important to keep, Char4"

Notice how the gsub approach has a different result than the JSON parse method.

In theory, Ruby's eval could also be used to parse the string data into an array and then join it, but eval is meant for interpreting strings and running them as ruby code, and as such should only be used when it is important to run arbitrary ruby code that has been encoded as a string. The method name 'eval' actually comes from the word 'evaluate', not evil. Despite this, however, evaluation is not an objective in this scenario; parsing is.

Another reason why people are hesitant to recommend eval for trivial tasks like data parsing is that the worst case scenario of JSON#parse is that it fails to parse. Whereas the worst case scenario of eval is that you've completely deleted your file system by parsing a string that you didn't expect to be there when you first designed your code.

Ninjaxor
  • 876
  • 12
  • 27
-4

I don't think gsub is the right way to go.

eval("[\"This is a word ect\", \"Char2\", \"Another grooup\", \"Char4\"]")
.join(", ")
# => "This is a word ect, Char2, Another grooup, Char4"

Keep in mind that eval() can be dangerous. The reason it is not dangerous in this circumstance is because we are dealing with a fixed string. For more information, have a look at When is `eval` in Ruby justified?

Community
  • 1
  • 1
sawa
  • 165,429
  • 45
  • 277
  • 381
  • @ma_il Marked your comment as non-constructive. How and who would you inject code into a prepared (fixed) string? – sawa Apr 29 '15 at 15:53
  • 4
    If it were fixed he wouldn't need processing, he could just replace the fixed string with the one he wanted. – Marcus Ilgner Apr 29 '15 at 15:54
  • 1
    I will have a variable which contains the string e.g. mod so it will be eval(mod).join(", ") – DMH Apr 29 '15 at 15:57
  • 10
    Recommending `eval()` could lead people to make huge mistakes. – Roman Kiselenko Apr 29 '15 at 16:00
  • 2
    @carrieKendall The OP does not in fact have a fixed string, so the use of eval here is not in fact safe, contrary to your statement. If it *were* fixed (even though it's not) then using eval would *still* be wrong, as you're needlessly creating a new instance of the compiler to do a trivial translation that could instead be done before even compiling the code, making the code faster, safer, and easier to read/maintain. Using eval is causing nothign but problems. – Servy Apr 29 '15 at 17:07
  • @Servy How do you know it is not fixed? The OP only showed a single example, and referred to it with the definite article. – sawa Apr 29 '15 at 17:08
  • You don't need to evaluate this type of data with Ruby, parsing with JSON is more than sufficient. – Ninjaxor Apr 29 '15 at 17:08
  • 1
    @sawa See [his comment](http://stackoverflow.com/questions/29948276/gsub-for-removing-brackets-and-from-string/29948568#comment48018508_29948568) And even if the string were in fact fixed, this would still be the wrong approach. – Servy Apr 29 '15 at 17:09
  • @Ninjaxor Yes. That would work if you know that the string is from JSON. – sawa Apr 29 '15 at 17:10
  • 1
    @CarrieKendall Then that would make the answer not answering the question, if it's only valid in the event the string is fixed (not that even that is an acceptable situation to use `eval`). – Servy Apr 29 '15 at 17:11
  • 1
    I can’t believe that absolutely correct answer continues yielding downvotes just because of [wrong] mantra “`eval` is evil.” Upvoted. – Aleksei Matiushkin Apr 29 '15 at 17:11
  • 3
    @mudasobwa I can't believe that a clearly *actively harmful* answer would be upvoted. Do you enjoy misleading less experienced developers into using actively harmful solutions due to their inability to recognize how problematic such a solution is, despite it's appearance at being helpful to the uneducated programmer? – Servy Apr 29 '15 at 17:13
  • 3
    @Servy Let me make things clear. My answer you may find below, it uses safe `JSON.parse`. @sawa’s answer is correct. It is by no means harmful. It performs the requested operation. Whether `eval` was evil, Matz would not include it in language, would he? Now we have your word “harmful solution” against Matz’ word ”`eval` is to be presented in the language”. I trust Matz more, sorry for that. Yes, there are circumstances where `eval` in not applicable. This is by no means such a case. Possibly @sawa should drop a notice “be careful,” but even despite he did not, his answer is still correct. – Aleksei Matiushkin Apr 29 '15 at 17:19
  • 1
    @mudasobwa Thanks for that. I agree with you. You answer after the edit is actually good. – sawa Apr 29 '15 at 17:23
  • 2
    @CarrieKendall I have never said “someone,” I said “Matz.” – Aleksei Matiushkin Apr 29 '15 at 17:24
  • 3
    @mudasobwa You think that ruby can ever do anything harmful? So you think that there's no way you could cause any harm by deleting a file, or editing the registry, spinning the CPU, or trapping keyboard input? I never said that using `eval` was universally harmful. I said that it's use of it here was, because, among other points, it's completely unnecessary. At *best* it's just wasting a huge amount of effort and adding a lot of complexity. That's even ignoring all of the security vulnerabilities. Apparently you just don't *care* about all of the problems this answer is likely to cause. – Servy Apr 29 '15 at 17:31
  • OK, things are getting a little too heated here. Let's refrain from insulting anyone and try to keep this from devolving into a flamewar. – Brad Larson Apr 29 '15 at 18:34
  • @awal I was trying to lighten the tense mood with a joke, sorry if it was perceived as anything different. I am going to remove all my comments since they don't add anything to the answer. – Carrie Kendall May 01 '15 at 13:35